WPF 中的 Datagrid 和 sql 数据表与其他方法

发布于 2024-12-09 14:19:39 字数 289 浏览 1 评论 0原文

这是我尝试做的。我想在数据网格内提供产品的就地编辑。首先,我将 List 包装到 ObservableCollection 中,并为每个 POCO 实现了 INotifyPropertyChanged 接口。撤消更改并跟踪已更改的内容以提交似乎很困难,而且我遇到了很多问题。而且我觉得在属性更改时为每个 poco 创建如此多的事件处理程序并不好奇怪...
所以我想问 DataTable 是否解决了这些问题?即使它解决了验证问题?它对 POCO 一无所知......还有其他更好的解决方案吗?

Here is what i tried to do.. I want to provide an in place editing of products within a datagrid. Firstly i wrapped into a ObservableCollection a List<Product> and implemented INotifyPropertyChanged interface for each POCO. Undoing changes and tracking what has changed in order to commit seems hard and i had lots of problems.. Also i feel that creating so many event handlers for every single poco when a property changed is not good strange...
So i am asking does DataTable solve these problems ? Even it solves what about validation ?It doesnt know anything about the POCO.... Are any other better solutions for this ??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光沙漏 2024-12-16 14:19:39

属性更改处理程序并没有那么糟糕。下面是一个示例:

// Hook up a CollectionChanged event
ProductCollection.CollectionChanged += ProductCollection_Changed;

// In the Collection Changed event, hook up a PropertyChanged event
void ProductCollection_Changed(object sender, CollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach(Product item in e.NewItems)
            item.PropertyChanged += Product.PropertyChanged;
    }

    if (e.OldItems != null)
    {
        foreach(Product item in e.OldItems)
            item.PropertyChanged -= Product.PropertyChanged;
    }
}

// In the Product property changed event, do something.
// Usually I only use this for raising the CollectionChanged event when
// a property of an object inside a collection changes.
void Product_Changed(object sender, PropertyChangedEventArgs e)
{

}

就我个人而言,我更希望让每个 Product 跟踪它自己的更改,而不是在 ViewModel 中跟踪它们。首次创建产品时,保留原始数据的副本,并提供类似 UndoChanges() 方法的方法,该方法只需重新加载原始数据。

要跟踪各个属性的更改,我将在每个 Product 属性的 set 方法中执行此操作。这是因为 PropertyChanged 事件可以手动引发,并不一定意味着属性已更改。

private int _someValue;
public int SomeValue
{
    get { return _someValue; }
    set
    {
        if (value != _someValue)
        {
            // Track what's changed here. 
            // How you do it is based on what you want to track
            if (!ChangedProperties.Keys.Contains("SomeValue"))
            {
                ChangedProperties.Add(
                    new KeyValuePair<string, object>("SomeValue", _someValue));
            }

            _someValue = value;
            RaisePropertyChanged("SomeValue");
        }
    }
}

The property change handlers aren't that bad. Here's an example:

// Hook up a CollectionChanged event
ProductCollection.CollectionChanged += ProductCollection_Changed;

// In the Collection Changed event, hook up a PropertyChanged event
void ProductCollection_Changed(object sender, CollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach(Product item in e.NewItems)
            item.PropertyChanged += Product.PropertyChanged;
    }

    if (e.OldItems != null)
    {
        foreach(Product item in e.OldItems)
            item.PropertyChanged -= Product.PropertyChanged;
    }
}

// In the Product property changed event, do something.
// Usually I only use this for raising the CollectionChanged event when
// a property of an object inside a collection changes.
void Product_Changed(object sender, PropertyChangedEventArgs e)
{

}

Personally, I would prefer to have each Product track it's own changes, instead of tracking them in the ViewModel. When a product first gets created, keep a copy of the original data, and provide something like a UndoChanges() method that simply reloads the original data.

To track changes on individual properties, I would do that in the set method of each Product property. This is because the PropertyChanged event can be raised manually, and doesn't necessarily mean that the property has changed.

private int _someValue;
public int SomeValue
{
    get { return _someValue; }
    set
    {
        if (value != _someValue)
        {
            // Track what's changed here. 
            // How you do it is based on what you want to track
            if (!ChangedProperties.Keys.Contains("SomeValue"))
            {
                ChangedProperties.Add(
                    new KeyValuePair<string, object>("SomeValue", _someValue));
            }

            _someValue = value;
            RaisePropertyChanged("SomeValue");
        }
    }
}
却一份温柔 2024-12-16 14:19:39

DataTable 确实解决了一些问题......

  1. 当您不确定将有多少列时。
  2. 当频繁编辑时,编辑会发生在数据表上,如果数据表有约束,则会因无效条目而出错。因此可以保持一定程度的验证和数据完整性。
  3. 由于可查询,数据表通过使用其 DefaultView(即 DataView)进行排序和过滤,可以更快地产生结果。

话虽如此……

  1. 通过可观察集合可以更好地实现频繁更新,其中每个项目都实现了 INotifypropertyChanged。
  2. 使用Bindings 进行验证很容易实现。
  3. Datagrid 确实为集合的对象模型提供了比数据表更多的功能。

所以最终这是你的选择。不过,我不介意可观察的集合和 INotifyPropertyChanged 通知,因为它们似乎充分利用了 WPF DataGrid...样式和性能方面。

DataTable do solve a few things...

  1. When you are not sure how many columns you are going to have.
  2. When there are frequent edits, the edits take place onto the data table and if the data table has constraints then they will error out for invalid entries. So some level of validation and data integrity is maintained.
  3. Being queryable, the data tables produce faster results with sorting and filtering with their DefaultView i.e. DataView.

Having said that ...

  1. Frequent updates are better achieved by observable collection with each item having implemented INotifypropertyChanged.
  2. Validations using Bindings are easily achievable.
  3. Datagrid does provide some more features for object model of collections than data tables.

So ultimately its your choice. However I dont mind observable collections and INotifyPropertyChanged notifications as they seem to get the best out of WPF DataGrid... styling and performance wise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文