c# - 为什么更改 DataGrid ComboBox 值根本不会更新绑定(bind)属性?

标签 c# wpf mvvm combobox datagrid

我有 DataGridComboBoxColumn 应该显示整数或文本“默认”。当我添加行时,组合框从 viewmodel 的绑定(bind)属性中获取正确的值,但是当我在用户界面中更改值时,不会调用该属性的集合。我尝试了 SelectedValueBinding 和 SelectedItemBinding。转换器的 ConvertBack 永远不会被调用。我不知道应该调用它。

有效的东西:

  • DataGrid SelectedItem 绑定(bind)
  • 文本列双向绑定(bind)(此处省略)

  • 这是我的代码:

    XAML:
    <DataGrid Name="SelectionSetsGrid" CanUserAddRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" 
                          ItemsSource="{Binding SelectionSets}" AutoGenerateColumns="False"
                          SelectedItem="{Binding SelectedSelectionSet}">
     <DataGrid.Columns>
      <DataGridComboBoxColumn Header="Width" SelectedValueBinding="{Binding LineWidthIndex}">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox" BasedOn="{StaticResource Theme.ComboBox.Style}">
                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LineWidths}"/>
                <Setter Property="IsReadOnly" Value="True"/>
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <WrapPanel>
                                <TextBlock Text="{Binding Converter={StaticResource IntToIntTextOrDefaultConverter}}" VerticalAlignment="Center"/>
                            </WrapPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="ComboBox" BasedOn="{StaticResource Theme.ComboBox.Style}">
                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LineWidths}"/>
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <WrapPanel>
                                <TextBlock Text="{Binding Converter={StaticResource IntToIntTextOrDefaultConverter}}" VerticalAlignment="Center"/>
                            </WrapPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
      </DataGridComboBoxColumn>
     </DataGrid.Columns>
    </DataGrid>
    

    ViewModel(ViewModel 实现 INotifyPropertyChanged 和 SetValue 引发 PropertyChanged):
    public class SelectedObjectsViewModel : ViewModel
    {
        private int[] _lineWidths = { -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        public ObservableCollection<int> LineWidths { get; private set; };
    
        private ObservableCollection<SelectionSetViewModel> _selectionSets;
        public ObservableCollection<SelectionSetViewModel> SelectionSets
        {
            get { return _selectionSets; }
            set { this.SetValue(ref _selectionSets, value); }
        }
    
        private SelectionSetViewModel _selectedSelectionSet;
        public SelectionSetViewModel SelectedSelectionSet
        {
            get { return this._selectedSelectionSet; }
            set { this.SetValue(ref _selectedSelectionSet, value); }
        }
    }
    

    DataGrid 行的 ViewModel(ViewModel 实现 INotifyPropertyChanged 和 SetValue 引发 PropertyChanged):
    public class SelectionSetViewModel : ViewModel
    {
        public SelectionSetViewModel()
        {
            LineWidthIndex = -1;
        }
        private int _lineWidthIndex;
        public int LineWidthIndex
        {
            get { return _lineWidthIndex; }
            set { SetValue(ref _lineWidthIndex, value); }
        }
    

    转换器:
    public class IntToIntTextOrDefaultConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if ((int)value == -1)
                return Fusion.App.Current.Resources["StrDefault"].ToString();
    
            return value.ToString();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            return value.Equals(true) ? parameter : Binding.DoNothing;
        }
    }
    

    最佳答案

    似乎在某些情况下,例如在编辑文本列并按 enter 或添加新行之后,属性实际上在更改组合框值后更新(设置调用)。所以我只是将 UpdateSourceTrigger=PropertyChanged 添加到绑定(bind)中,并且对源属性的更新立即发生(而不是在一些随机操作之后)。请注意,从 ComboBox 更改焦点不足以更新源属性,所以我认为它从未更新。

    <DataGrid Name="SelectionSetsGrid" CanUserAddRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" 
                  ItemsSource="{Binding SelectionSets}" AutoGenerateColumns="False"
                  SelectedItem="{Binding SelectedSelectionSet}">
            <DataGridComboBoxColumn Header="{StaticResource XpStrTopologyWidth}" SelectedItemBinding="{Binding LineWidthIndex, UpdateSourceTrigger=PropertyChanged}">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox" BasedOn="{StaticResource Theme.ComboBox.Style}">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LineWidths}"/>
                        <Setter Property="IsReadOnly" Value="True"/>
                        <Setter Property="ItemTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <WrapPanel>
                                        <TextBlock Text="{Binding Converter={StaticResource IntToIntTextOrDefaultConverter}}" VerticalAlignment="Center"/>
                                    </WrapPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox" BasedOn="{StaticResource Theme.ComboBox.Style}">
                        <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LineWidths}"/>
                        <Setter Property="ItemTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <WrapPanel>
                                        <TextBlock Text="{Binding Converter={StaticResource IntToIntTextOrDefaultConverter}}" VerticalAlignment="Center"/>
                                    </WrapPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>                        
        </DataGrid.Columns>
    </DataGrid>
    

    关于c# - 为什么更改 DataGrid ComboBox 值根本不会更新绑定(bind)属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39561093/

    相关文章:

    c# - 如何在不引用数据库的情况下在 WPF MVVM 应用程序中创建报告

    android - 缺少主调度程序的模块

    c# - 我可以从 C# 表单运行 Windows 命令吗?

    c# - 通用存储库添加自定义方法

    c# - 让文本与 TextBlock 的顶部齐平(不是 VerticalAlignment,我保证!)

    c# - 从DataGrid按钮获取CommandParameter

    sql - 如何让 INotifyPropertyChanged 从存储在 SQL 中的列表中更新绑定(bind)项目?

    wpf - 使用值转换器时如何更新 View 模型的属性?

    c# - 通过 GraphQL 将任何 SQL Server 数据库变成可查询的

    c# - Mysql 查询在作为文本传递到数据库时抛出错误,但作为存储过程工作