Проблема обновления привязки LINQ - PullRequest
0 голосов
/ 30 ноября 2010

У меня есть ListView, связанный с объектом LINQ to SQL.Когда я дважды щелкаю статью в ListView, она открывает окно сведений о статье и позволяет пользователю изменять свойства статьи.

Пока все работает нормально, но когда пользователь сохраняет и закрывает детали статьи,ListView не отражает сделанные изменения (например, описание статьи).Я не хочу реализовывать INotifyPropertyChanged во всех моих классах LINQ, потому что я использую VS2010 для генерации моей схемы таблиц Linq, поэтому было бы больно изменять автоматически сгенерированный код конструктора ... (и это, безусловно, будет отменять все мои изменения каждый разЯ внесу изменения в схему таблицы)

Как я могу просто заставить ListView обновить привязку LINQ при закрытии окна сведений?

Заранее благодарен за помощь.

Ответы [ 2 ]

1 голос
/ 30 ноября 2010

Быстрое и простое решение состоит в том, чтобы использовать декоратор 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

1 голос
/ 30 ноября 2010

Все классы Linq генерируются как частичные классы - это означает, что вы можете создать свой собственный частичный класс, который соответствует классу Linq, и добавить любые дополнительные функциональные возможности, необходимые для него. Затем, когда он скомпилирован, он будет работать как один класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...