WPF DependencyProperty链式通知

4

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

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

现在我试图扩展这个例子:我想要创建一个“中间类”,在XElement和UI之间进行绑定,并将它们全部连接到一起,这样,如果我对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;
    }

Book是一个代表书籍的类,现在只有一个名称属性。

UI类缺失,但它应该绑定到公共List<Book> BookList,并在ListBox中向用户展示书名。

有人知道为什么我没有收到任何通知...或者我该怎么做才能保持公共List<Book> BookList与私有IEnumerable<XBookList>同步吗?

1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接