WPF DependencyProperty Chain Notification

im exploring the world of WPF, I find a great example on the web on how to use binding in xml

http://www.codeproject.com/Articles/37854/How-to-Perform-WPF-Data-Binding-Using-LINQ-to-XML

Now I'm trying to extend this example: I want to create a “middle class” between the XElement and the user interface and bind all the togheder in the chain, so if I have a modification in xml, then I add the property to the middle class, the updated user interface.

Here is the code:

This is the class that wraps XElement

 public class XElementDataProvider : ObjectDataProvider { public XElementDataProvider() { ObjectInstance = XElement.Load(@"C:\MyFile.xml"); } private static XElementDataProvider instance; public static XElementDataProvider Instance { get { if (instance == null) { instance = new XElementDataProvider(); } return instance; } } } 

This is MiddleClass

 public class MiddleClass : DependencyObject { XElementDataProvider xElementDataProvider; XElement myxml; public MiddleClass() { //here i get my dataprovider xElementDataProvider = XElementDataProvider.Instance; myxml = xElementDataProvider.Data as XElement; //i bind my internal collection to the Elements... Binding binding = new Binding("Elements[book]") { Source = myxml, Mode = BindingMode.Default//here i cant use TwoWay, give me //back an exeption }; BindingOperations.SetBinding(this, XBookListProperty, binding); //just to have confirmation of the adding myxml.Changed += new EventHandler<XObjectChangeEventArgs (myxml_Changed); } void myxml_Changed(object sender, XObjectChangeEventArgs e) { } //i use a DependencyProperty to have also a change callback public static readonly DependencyProperty XBookListProperty = DependencyProperty.Register("XBookList", typeof(IEnumerable), typeof(MiddleClass), new PropertyMetadata(XBookPropertyChanged) ); //here i have a notification only at start but no when i add a new book private static void XBookPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MiddleClass middleClass = d as MiddleClass; middleClass.XBookPropertyChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue); } private void XBookPropertyChanged(IEnumerable old, IEnumerable newValue) { } //this is the propery i finally want to expose to the UI but im not able //to keep updated public List<Book> bookList; public List<Book> BookList { get { return bookList; } set { bookList = value; } } //this is my internal list binded to the xml private IEnumerable XBookList { get { return (IEnumerable)GetValue(XBookListProperty); } set { SetValue(XBookListProperty, value); } } //here i try to add a book addind direcly to the xml//i expect a //notification of propery changed...but nothing public bool AddBook(string name) { XElement newWorkSheet = new XElement("Book", new XAttribute("Name", name) ); myxml.Add(newWorkSheet); return true; } 

A book is a class that represses a book, and for now, let it have only a name.

Invalid user interface class, but must bind to public List<Book> book lists and display book names to the user in the ListBox

Enyone knows why I am not receiving any notification ... or what do I need to do to make the public List<Book> BookList synchronize with the private IEnumerable<XBookList> ?

+4
source share
1 answer

OK, after many attempts, the only solution I found is the following:

in order to have notifications when something changes in IEnumerable<XBookList> , you need to clear it from re-binding after changing it.

Thus, you have the first, unused notification of a clear and then new notification of a new set.

Then in the handler you can synchronize the new list with the old one.

 public bool AddBook(string name) { XElement newWorkSheet = new XElement("Book", new XAttribute("Name", name) ); myxml.Add(newWorkSheet); ClearValue(XBookListProperty); Binding binding = new Binding("Elements[book]") { Source = myxml, Mode = BindingMode.Default }; BindingOperations.SetBinding(this, XBookListProperty, binding); return true; } 
0
source

Source: https://habr.com/ru/post/1440541/


All Articles