【问题标题】:Catching which cell changed in editable datagrid捕捉可编辑数据网格中更改的单元格
【发布时间】:2012-03-24 12:00:42
【问题描述】:

我在 VB WPF 应用程序中有一个可编辑的 DataGrid。 DataGrid 本身将其 SourceUpdated 属性设置为我的事件处理程序。网格中的 2 个列是可编辑的,并且它们在 Binding 中的 NotifyOnSourceUpdated 标志设置为 True。该事件正在正确触发,但我似乎无法找出确定发生了什么变化的最佳方法。两列相互依赖,其中一列是项目数量,另一列是案例数量。如果用户更改其中一个,我想重新计算另一个值并更新网格以及绑定源。我敢肯定有很多方法可以解决这个问题,但我很好奇什么是最好的方法。我可以在数据网格上监听 change 事件,查看发生了什么变化,设置一些变量,然后在 SourceUpdated 事件中使用这些变量,但这似乎并不优雅。有什么建议吗?

【问题讨论】:

  • 要求“最佳”方式会导致主观回答,并且在 S.O. 中通常不鼓励这样做。但是我对您问题的措辞感到困惑:您是否正在寻找一种方法来确定哪个单元格触发了更改事件?
  • 了解“最佳”关注点……我的错。但是,是的,基本上,这就是我要问的,但我认为 AngelWPF 的回答会满足我的需要。我的数据网格绑定到一个 ObservableCollection,但我对这些东西还是新手,并没有考虑 PropertyChanged 事件。我会试试看效果如何

标签: wpf vb.net visual-studio wpf-controls


【解决方案1】:

我建议你走出事件处理程序的世界! WPF 不鼓励在事件处理程序中使用旧的 WinForms 方法。

MVVM方式....

您必须以 MVVM 方式利用模型类的强大功能。绑定到您的数据网格的集合必须是一些项目的集合......例如如果您的数据网格显示Employees 的列表,那么您的集合必须是一些IEnumerable<Employee> ...所以Employee 类可以在这里为您提供帮助。

假设您的数据网格将GenderSaluation 显示为两个相互关联的可编辑列。所以你的Employee 班级应该有以下内容......

1. `Employee` class must implement `INotifyPropertyChanged` interface.
2. `Gender` and `Salutation` properties must raise the `PropertyChanged` event from their property setters.
3. In the setter of `Gender` \ `Salutation` we must write the logic of changing the other field.

例如

            private string _gender;
    public string Gender
    {
        get
        {
            return _gender;
        }

        set
        {
            if (_gender != value)
            {
                _gender = value;

                if (_gender == "Male")
                {
                    Salutation = "Mr";
                }
                else if (_gender == "Female"
                     && (Salutation == "Mr" || string.IsNullOrEmpty(Salutation)))
                {
                    Salutation = "Ms";
                }
                else if (string.IsNullOrEmpty(_gender))
                {
                    Salutation = string.Empty;
                }

                OnPropertyChanged("Gender");
            }
        }
    }

    private string _salutation;
    public string Salutation
    {
        get
        {
            return _salutation;
        }

        set
        {
            if (_salutation != value)
            {
                _salutation = value;

                if (_salutation == "Mrs" || _salutation == "Ms")
                {
                    Gender = "Female";
                }
                else if (_salutation == "Mr")
                {
                    Gender = "Male";
                }
                else if (string.IsNullOrEmpty(_salutation))
                {
                    Gender = string.Empty;
                }

                OnPropertyChanged("Salutation");
            }
        }
    }

OnPropertyChanged() 是……

    public void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

这样您的 GUI 将自动执行相关字段的转换。

ValueConverter 方式 ...

如果您的字段不存储到模型中而仅用于显示目的,那么您可以使用ValueConverter....

public class GenderToSalutationConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert
        (object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        var _gender = (string) value;
        if (_gender == "Male")
        {
            return "Mr";
        }
        else if (_gender == "Female")
        {
            return "Ms";
        }

        return string.Empty;
    }

    public object ConvertBack
           (object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
    {
        var _salutation = (string)value;
        if (_salutation == "Mrs" || _salutation == "Ms")
        {
            return "Female";
        }
        else if (_salutation == "Mr")
        {
            return "Male";
        }

        return string.Empty;
    }

    #endregion
}

XAML

   <UserControl.Resources>
       <local:GenderToSalutationConverter x:Key="GenderToSalutationConverter"/>
   </UserControl.Resources>
   <tk:DataGrid ItemsSource="{Binding Employees}">
        <tk:DataGrid.Columns>
             <tk:DataGridTextColumn
                        Header="Sex"
                        Binding="{Binding Gender,
                           Converter={StaticResource GenderToSalutationConverter}}">
            </tk:DataGridTextColumn>
            <tk:DataGridTextColumn
                        Header="Title"
                        Binding="{Binding Salutation}">
            </tk:DataGridTextColumn>
        </tk:DataGrid.Columns>
    </tk:DataGrid>

希望这会有所帮助...

【讨论】:

  • 我已经有大部分了(即,我的集合是 ObservableCollection 并且集合中的对象确实实现了 INotifyPropertyChanged 等)。我错过了关于引发 PropertyChanged 事件的文章。现在工作得很好。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多