2010-11-30 10 views
0

J'ai une ListView liée à un objet LINQ to SQL. Lorsque je double-clique sur un article dans ListView, il ouvre la fenêtre des détails de l'article et permet à l'utilisateur de modifier les propriétés de l'article.Problème d'actualisation de liaison LINQ

Jusqu'à présent, tout fonctionne bien, mais lorsque l'utilisateur enregistre et ferme les détails de l'article, le ListView ne reflète pas les modifications apportées (comme la description de l'article par exemple). Je ne veux pas implémenter INotifyPropertyChanged dans toutes mes classes LINQ parce que j'utilise VS2010 pour générer mon schéma de table Linq, donc ce serait difficile de modifier le code du concepteur généré automatiquement ... (et il remplacera certainement tous mes changements à chaque fois Je vais apporter une modification au schéma de la table)

Comment puis-je simplement forcer le ListView à actualiser la liaison LINQ lorsque la fenêtre de détails est fermée?

Merci d'avance pour votre aide.

Répondre

1

Toutes les classes Linq sont générées en tant que classes partielles - cela signifie que vous pouvez créer votre propre classe partielle qui correspond à la classe Linq et ajouter toutes les fonctionnalités supplémentaires requises. Ensuite, quand il est compilé, tout fonctionnera comme une classe.

+0

Je n'ai pas remarqué ça ^^ Thank – Karnalta

1

Une solution rapide et facile est d'utiliser un décorateur DynamicObject pour ajouter le changement de comportement de notificcation sans avoir à changer vos classes d'origine, ou d'écrire une suite de définitions de classes partielles

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; 
    } 
} 

et Heres un échantillon useage:

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; 
    } 
} 

détails se trouvent sur un billet de blog, j'ai écrit particulièrement sur cette questions http://www.deanchalk.me.uk/post/WPF-e28093-Easy-INotifyPropertyChanged-Via-DynamicObject-Proxy.aspx