Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF DependencyProperty链通知_Wpf_Binding_Notifications_Dependency Properties_Dependencyobject - Fatal编程技术网

WPF DependencyProperty链通知

WPF DependencyProperty链通知,wpf,binding,notifications,dependency-properties,dependencyobject,Wpf,Binding,Notifications,Dependency Properties,Dependencyobject,我正在探索WPF世界,我在网上找到了一个关于如何在xml上使用绑定的好例子 现在我试图扩展这个例子:我想在 xBase< /Cube >和UI之间创建一个“中间类”,并在一个链中绑定所有的ToHeHER,因此,如果我对XML进行了修改,那么我就在中间类中更新了属性,然后UI也更新了。 下面是一些代码: 这是包装XElement public class XElementDataProvider : ObjectDataProvider { public XElementDataProv

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

现在我试图扩展这个例子:我想在<代码> xBase< /Cube >和UI之间创建一个“中间类”,并在一个链中绑定所有的ToHeHER,因此,如果我对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;
        }

    }
}
这是
中产阶级

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;
    }
公共类中间类:DependencyObject
{
XElementDataProvider XElementDataProvider;
XElement myxml;
公共中产阶级()
{
//这是我的数据提供者
xElementDataProvider=xElementDataProvider.Instance;
myxml=xElementDataProvider。数据为XElement;
//我将我的内部集合绑定到元素。。。
绑定绑定=新绑定(“元素[书本]”)
{
Source=myxml,
Mode=BindingMode.Default//这里我不能双向使用,请给我//返回一个exeption
};
BindingOperations.SetBinding(this,XBookListProperty,binding);
//只是为了确认添加

myxml.Changed+=neweventhandlerOK,经过多次尝试,我找到的唯一解决方案是:

要在
IEnumerable
中发生更改时发出通知,您需要在修改后将其清除并重新绑定

这样,您就有了关于清除的第一个未使用的通知,然后是关于新集合的另一个通知

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

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