无法将组合框绑定到WPF中的DataGrid列

flseospp  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(208)

我正在尝试将组合框绑定到DataGrid中的字段,但无法更新该字段。
下面是来自xaml的ComboBox:

<ComboBox Grid.Row="6" Grid.Column="1" x:Name="cmbBedArea" HorizontalAlignment="Left" VerticalAlignment="Center" SelectedValue="{Binding ElementName=gridUsers, Path=SelectedValue.BedArea, Mode=OneTime}" Width="200"/>

下面是完整的xaml文件:

<Window x:Class="WinPharm.Net.frmDbUsers"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WinPharm.Net"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="WinPharm User Management" Height="450" Width="800">

    <Window.Resources>
        <Style x:Key="spacerRow" TargetType="RowDefinition">
            <Setter Property="Height" Value="10"/>
        </Style>
    </Window.Resources>

    <Grid>
        <!--Users Grid-->
        <DataGrid
            x:Name="gridUsers" 
            VerticalAlignment="Top" 
            Height="150" 
            Margin="10,10,10,0" 
            IsReadOnly="True" 
            AutoGenerateColumns="False" 
            GridLinesVisibility="All" 
            AlternatingRowBackground="LightGray"
            SelectionMode="Single"
            SelectionUnit="FullRow" 
            Loaded="gridUsers_Loaded" 
            SelectionChanged="gridUsers_SelectionChanged"            
            >
            <DataGrid.Columns>
                <DataGridTextColumn Header="" Width="20"/>
                <DataGridTextColumn x:Name="LoginId" Header="Id" Width="150" Binding="{Binding LoginID}"/>
                <DataGridTextColumn x:Name="Name" Header="Name" Width="200" Binding="{Binding Name}"/>
                <DataGridTextColumn x:Name="BedArea" Header="Bed Area" Width="200" Binding="{Binding BedArea}"  />
            </DataGrid.Columns>
        </DataGrid>
        <!--Form Fields-->
        <Grid Margin="10,175,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Height="Auto" Width="400">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition Style="{StaticResource spacerRow}"></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition Style="{StaticResource spacerRow}"></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition Style="{StaticResource spacerRow}"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"></ColumnDefinition>
                <ColumnDefinition Width="280"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Content="Login Id:" HorizontalAlignment="Right" VerticalAlignment="Top"/>
            <TextBox IsEnabled="False" Grid.Row="0" Grid.Column="1" x:Name="txtLoginId" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ElementName=gridUsers, Path=SelectedItem.LoginID}" Width="200" MaxLength="50"/>

            <Label Grid.Row="2" Grid.Column="0" Content="Name:" HorizontalAlignment="Right" VerticalAlignment="Top"/>
            <TextBox Grid.Row="2" Grid.Column="1" x:Name="txtName" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ElementName=gridUsers, Path=SelectedItem.Name, Mode=OneWay}" Width="200" MaxLength="50"/>

            <Label Grid.Row="4" Grid.Column="0" Content="External Id:" HorizontalAlignment="Right" VerticalAlignment="Top"/>
            <TextBox Grid.Row="4" Grid.Column="1" x:Name="txtExternalId" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding ElementName=gridUsers, Path=SelectedItem.ID_External, Mode=OneWay}" Width="200" MaxLength="50"/>

            <Label Grid.Row="6" Grid.Column="0" Content="Bed Area:" HorizontalAlignment="Right" VerticalAlignment="Top"/>
            <ComboBox Grid.Row="6" Grid.Column="1" x:Name="cmbBedArea" HorizontalAlignment="Left" VerticalAlignment="Center" SelectedValue="{Binding ElementName=gridUsers, Path=SelectedValue.BedArea, Mode=OneTime}" Width="200"/>
        </Grid>
        <!--Form Buttons-->
        <Grid HorizontalAlignment="Center" VerticalAlignment="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"></ColumnDefinition>
                <ColumnDefinition Width="120"></ColumnDefinition>
                <ColumnDefinition Width="120"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button x:Name="btnAdd" Grid.Column="0" Content="Add" Height="40" Width="100" Margin="10,0,0,10" Click="btnAdd_Click"></Button>
            <Button x:Name="btnDelete" Grid.Column="1" Content="Delete" Height="40" Width="100" Margin="10,0,0,10" Click="btnDelete_Click"></Button>
            <Button x:Name="btnUpdate" Grid.Column="2" Content="Update" Height="40" Width="100" Margin="10,0,0,10" Click="btnUpdate_Click"></Button>
        </Grid>
    </Grid>
</Window>

你知道为什么ComboBox没有更新吗?
我把这个放到后面的代码中,并能够让它更新,但我想在没有这个代码的情况下这样做。

private void gridUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var drv = ((DataRowView)((DataGrid)sender).SelectedItem).Row;
            if (drv != null)
            {
                cmbBedArea.SelectedValue = drv["BedArea"];
            }
        }
rhfm7lfc

rhfm7lfc1#

也许你会把BindingMode.OneTimeBindingMode.OneWay搞混。
BindingMode.OneTime意味着绑定将只读取绑定源 * 一次 *(因此绑定模式的名称)。数据源的任何后续更新都将被忽略。
另一方面,BindingMode.OneWay将在Binding对象的生命周期内跟踪任何绑定源更改。
BindingMode.OneTime仅在您不希望数据源发生更改(或者您只对初始值感兴趣)时使用。这将提高应用程序的性能,因为绑定引擎不需要监视绑定源来检测更改。

  • “我也不清楚为什么默认模式有效而OneTime无效。"*

ComboBox.SelectedValue属性的默认绑定模式是BindingMode.TwoWay--这就是默认模式有效的原因。它更新绑定源和目标(双向)。大多数依赖项属性默认为BindingMode.OneWay)。
此时,您应该已经理解了BindingMode.OneTime只允许目标(ComboBox)更新一次-一次绑定。

  • “但是,我希望在更改组合框时网格不会更新。"*

在这种情况下,必须将Binding.Mode属性显式更改为BindingMode.OneWay。这样,ComboBox将只接收更改,而不会发送更改。请记住,SelectedValue属性的默认值是BindingMode.TwoWay,这当然会允许ComboBox更新DataGrid
BindingMode.OneWay是配置值。

<!-- Unless you also define the 'SelectedValuePath' 
     you should use the 'SelectedItem' property instead of 'SelectedValue' -->
<ComboBox SelectedItem="{Binding Mode=OneWay, Path=SelectedItem.BedArea, ElementName=gridUsers}" />

<!-- Alternative version using 'SelectedValuePath' and 'SelectedValue'-->
<ComboBox SelectedItem="{Binding Mode=OneWay, Path=SelectedValue, ElementName=gridUsers}" />
<DataGrid x:Name="gridUsers"
          SelectedValuePath="BedArea" />

一般来说,如果您想要更新(绑定目标和/或绑定源):将Binding.Mode设置为BindingMode.OneWayBindingMode.TwoWayBindingMode.OneWayToSource
没有更新:BindingMode.OneTime.
参见BindingMode

相关问题