DataContext Refresh和PropertyChanging& PropertyChanged事件

时间:2009-03-05 02:50:33

标签: linq linq-to-sql datacontext inotifypropertychanged

我正处于一种情况,我从外部来源获悉某个特定实体已在我当前的datacontext之外被更改。我能够找到实体并像这样调用刷新

MyDataContext.Refresh(RefreshMode.OverwriteCurrentValues,myEntity);

并且正确更新了实体上已更改的属性。但是,当刷新发生时,INotifyPropertyChanging INotifyPropertyChanged似乎都没有出现,这使我的UI显示不正确的信息。

我知道Refresh()无法在实体上使用正确的属性getter和setter来引发更改通知事件,但也许有另一种方法可以完成同样的事情?

我做错了吗? 有比Refresh更好的方法吗? 如果刷新是唯一的选择,有没有人有解决方法?

2 个答案:

答案 0 :(得分:2)

我有类似的问题。我绑定到TreeView并需要调用Refresh以响应用户取消编辑操作。 Refresh()方法顺从地放回所有原始值,但这并没有反映在我的TreeView UI中。在与全能的谷歌商量后,我遇到了这个解决方案:

CollectionViewSource.GetDefaultView(treeViewClusters.ItemsSource).Refresh();

这似乎迫使我的TreeView更新所有内容。唯一的缺点(并且它是一个非常重要的缺点)是它似乎折叠了所有树节点,这导致用户失去它们的位置。我也可以将我的ItemsSource设置为null并再次返回...同样的效果,尽管如果你有一堆绑定的文本框或其他东西,这种方法会更简单,因为你不需要重新绑定每一个单身。

有比这更好的解决方案吗?

<强> EDITED: 是的,有......

我的一个比我更聪明的同事提出了这个解决方案,这似乎可以解决问题。在Linq2Sql对象的部分类中,添加以下代码:

public void SendPropertiesChanged()
{
     foreach (System.Reflection.PropertyInfo prop in this.GetType().GetProperties())
     SendPropertyChanged(prop.Name);
}

您可以在应用程序代码中调用它:

context.Refresh(RefreshMode.OverwriteCurrentValues, employee);
employee.SendPropertiesChanged();

所有UI元素都会收到消息,并自行更新。这甚至适用于树视图控件以及您不希望在刷新绑定时UI显示为“重置”的内容。

答案 1 :(得分:0)

如果您知道调用Refresh(),为什么不继续在那时刷新UI?

通过在LINQtoSQL DBML生成的实体类上调用setter来调用PropertyChanging和PropertyChanged。调用Refresh()不会这样做:

[Column(Storage="_DisplayName", DbType="VarChar(50) NOT NULL", CanBeNull=false)]
public string DisplayName
{
    get
    {
        return this._DisplayName;
    }
    set
    {
        if ((this._DisplayName != value))
        {
            this.OnDisplayNameChanging(value);
            this.SendPropertyChanging();
            this._DisplayName = value;
            this.SendPropertyChanged("DisplayName");
            this.OnDisplayNameChanged();
        }
    }
}