LINQ绑定刷新问题

时间:2010-11-30 10:32:57

标签: wpf linq binding

我有一个绑定到LINQ to SQL对象的ListView。当我双击ListView中的文章时,它会打开文章详细信息窗口,并允许用户更改文章属性。

到目前为止,一切正常,但是当用户保存并关闭文章详细信息时,ListView不会反映所做的更改(例如文章的描述)。我不想在所有LINQ类中实现INotifyPropertyChanged,因为我使用VS2010来生成我的Linq表模式,因此更改自动生成的设计器代码会很痛苦...(并且它肯定会每次都覆盖我的所有更改我将对表的架构进行更改)

如何在关闭详细信息窗口时强制ListView刷新LINQ绑定?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

所有Linq类都生成为部分类 - 这意味着您可以创建自己的与Linq类匹配的部分类,并添加其中所需的任何额外功能。然后在编译时,它将作为一个类工作。

答案 1 :(得分:1)

快速简便的解决方案是使用DynamicObject装饰器添加更改通知行为,而无需更改原始类或编写一组部分类定义

public class DynamicBindingProxy<T> : DynamicObject, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private static readonly Dictionary<string, Dictionary<string, 
        PropertyInfo>> properties = new Dictionary<string, 
            Dictionary<string, PropertyInfo>>();
    private readonly T instance;
    private readonly string typeName;

    public DynamicBindingProxy(T instance)
    {
        this.instance = instance;
        var type = typeof(T);
        typeName = type.FullName;
        if (!properties.ContainsKey(typeName))
            SetProperties(type, typeName);
    }

    private static void SetProperties(Type type, string typeName)
    {
        var props = type.GetProperties(
            BindingFlags.Public | BindingFlags.Instance);
        var dict = props.ToDictionary(prop => prop.Name);
        properties.Add(typeName, dict);
    }

    public override bool TryGetMember(GetMemberBinder binder, 
        out object result)
    {
        if (properties[typeName].ContainsKey(binder.Name))
        {
            result = properties[typeName][binder.Name]
                .GetValue(instance, null);
            return true;
        }
        result = null;
        return false;
    }

    public override bool TrySetMember(SetMemberBinder binder, 
        object value)
    {
        if (properties[typeName].ContainsKey(binder.Name))
        {
            properties[typeName][binder.Name]
                .SetValue(instance, value, null);
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(binder.Name));
            return true;
        }
        return false;
    }
}

并且是一个样本用法:

public partial class MainWindow : Window
{
    private readonly TestObj tObj;
    private DynamicBindingProxy<TestObj> dynObj;
    public MainWindow()
    {
        InitializeComponent();
        tObj = new TestObj() { Name = "test", Amount = 123.45, ID = 44, SomeDate = DateTime.Now };
        dynObj = new DynamicBindingProxy<TestObj>(tObj);
        DataContext = dynObj;
    }

    private void UpdateName(object sender, RoutedEventArgs e)
    {
        ((dynamic)dynObj).Name = newText.Text;
    }
}

完整的详细信息可以在我专门写这个问题的博客文章中找到 http://www.deanchalk.me.uk/post/WPF-e28093-Easy-INotifyPropertyChanged-Via-DynamicObject-Proxy.aspx