WPF DependencyProperty链通知

时间:2012-10-18 12:50:05

标签: wpf binding notifications dependency-properties dependencyobject

我正在探索WPF世界,我在网上找到了一个很好的例子,说明如何在xml上使用绑定

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

现在我试图扩展这个例子:我想在XElement和UI之间创建一个“中间的类”并绑定链中的所有togheder,所以,如果我对xml进行了修改,然后我更新了中产阶级的属性,然后更新了UI。

这里有一些代码:

这是包装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;
        }

    }
}

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

本书是一本课程,是一本书,让它说它现在只有一个名字。

UI类未命中但它应绑定在公共List<Book> BookList上,并在ListBox

中向用户显示书名

Enyone知道为什么我没有收到任何通知...或者我必须做些什么来保持公共List<Book> BookList与私人IEnumerable<XBookList>同步?

1 个答案:

答案 0 :(得分:0)

好的,经过多次尝试,我找到的唯一解决方案就是这个:

要在IEnumerable<XBookList>发生变化后发送通知,您需要在修改后将其清除广告重新绑定。

通过这种方式,您可以获得有关新集的清除和另一个通知的第一个未使用的通知。

然后在处理程序中,您可以将新列表与旧列表同步。

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