用动态数据集替换WPF Usercontrol中的静态XmlDataProvider的正确方法是什么?

用动态数据集替换WPF Usercontrol中的静态XmlDataProvider的正确方法是什么?,wpf,data-binding,treeview,Wpf,Data Binding,Treeview,这个问题可能需要编辑,因为我不认为我一定知道最好的方法 我的WPF usercontrol的当前配置。 我有一个XmlDataProvider,它包含一些静态XML元素,我使用这些元素填充TreeView控件。 我目前使用HierarchycalDataTemplate绑定到TreeViewItem <HierarchicalDataTemplate x:Key="SiteTemplate" ItemsSource="{Binding XPath=pci}">

这个问题可能需要编辑,因为我不认为我一定知道最好的方法

我的WPF usercontrol的当前配置。 我有一个XmlDataProvider,它包含一些静态XML元素,我使用这些元素填充TreeView控件。 我目前使用HierarchycalDataTemplate绑定到TreeViewItem

    <HierarchicalDataTemplate x:Key="SiteTemplate" ItemsSource="{Binding XPath=pci}">
        <TextBlock Text="{Binding XPath=@Name}"/>
    </HierarchicalDataTemplate>
    <Style TargetType="TreeViewItem">
        <Setter Property="IsExpanded" Value="True"/>
    </Style>

树视图控制

 <TreeView ItemsSource="{Binding Source={StaticResource SharePointSites}}" 
                              ItemTemplate="{StaticResource SiteTemplate}" 

我无法访问我的Visual Studio环境,因此下面的代码将充满编译错误。。。所以请将其视为伪代码

假设您的Xml结构是这样的

<MyItem Name="Root"> 
    <MyItem Name="ABC"/> 
    <MyItem Name="PQR"> 
        <MyItem Name="IJK"/> 
    </MyItem> 
    <MyItem Name="XYZ"/> 
</MyItem> 

  • 通过转换器绑定您的ItemsSource,比如MyXmlToObjectDataSourceConverter

    <TreeView ItemsSource="{Binding Source={StaticResource SharePointSites},
           Converter={StaticResource MyXmlToObjectDataSourceConverter}}" ... />
    
    
    
  • 在MyXmlToObjectDataSourceConverter.Convert()方法中,返回以下内容

    public object Convert(...) 
    { 
        return new ObservableCollection<XmlNodeWrapper>(
            ((XmlDataProvider)value).Document.SelectNodes("MyItem").Select( 
                d => new XmlNodeWrapper(d)).ToList()) 
    }
    
    公共对象转换(…)
    { 
    返回新的ObservableCollection(
    ((XmlDataProvider)值)。Document.SelectNodes(“MyItem”)。Select(
    d=>新的XmlNodeWrapper(d)).ToList()
    }
    
  • XmlNodeWrapper类将在内部维护“节点”,以便在通过属性设置器进行更新时, 您可以将基于节点的属性更新回。。。像这样

    public class XmlNodeWrapper : INotifyPropertyChanged
    { 
        private XmlNode node; 
        private ObservableCollection<XmlNodeWrapper> children; 
    
        public XmlNodeWrapper(XmlNode node) 
        { 
            this.node = node; 
        } 
    
        public ObservaleCollection<XmlNodeWrapper> Children 
        { 
            get 
            { 
                if (children == null) 
                { 
                    this.children 
                        = new ObservableCollection<XmlNodeWrapper>( 
                            this.node.ChildNodes.Select( 
                                d => new XmlNodeWrapper(d)).ToList()); 
                } 
    
                return children; 
            } 
        } 
    
        public string Name 
        { 
            get 
            { 
                return node.Attributes["Name"]; 
            } 
    
            set 
            { 
                node.Attributes["Name"] = value; 
                this.PropertyChanged["Name"]; 
            } 
        } 
    
        public event PropertyChangedEventHandler PropertyChanged; 
    
        private void PropertyChanged(String info) 
        { 
            if (PropertyChanged != null) 
            { 
                PropertyChanged(this, new PropertyChangedEventArgs(info)); 
            } 
        }
    } 
    
    公共类XmlNodeWrapper:INotifyPropertyChanged
    { 
    私有XmlNode节点;
    私生子;
    公共XmlNodeWrapper(XmlNode节点)
    { 
    this.node=节点;
    } 
    公众观察收集儿童
    { 
    得到
    { 
    if(children==null)
    { 
    这是我的孩子
    =新的可观测集合(
    this.node.ChildNodes.选择(
    d=>newxmlnodewrapper(d)).ToList();
    } 
    返回儿童;
    } 
    } 
    公共字符串名
    { 
    得到
    { 
    返回node.Attributes[“Name”];
    } 
    设置
    { 
    node.Attributes[“Name”]=值;
    此.PropertyChanged[“Name”];
    } 
    } 
    公共事件属性更改事件处理程序属性更改;
    私有void属性已更改(字符串信息)
    { 
    if(PropertyChanged!=null)
    { 
    PropertyChanged(此,新PropertyChangedEventArgs(信息));
    } 
    }
    } 
    
  • 然后用标准路径替换XAML中的所有XPath属性

    <HierarchicalDataTemplate x:Key="SiteTemplate"
        ItemsSource="{Binding Path=Children}"> 
            <TextBlock Text="{Binding Path=Name}"/> 
    </HierarchicalDataTemplate>
    
    
    

  • 你知道怎么做吗?@czuroski,不,对不起,我没有。一直忙于另一个项目,但仍在寻找答案。@czuroski,不幸的是,XmlDocument是.net中表示Xml的API。是不可见的。。。您可以访问的唯一方法是使用此代码。。。((XmlDataProvider)this.FindResource(“SharePointSites”)).Document.SelectNodes(“myroot”)。。。好的是这是一个ICollection,所以使用LINQ、.ToList()和new ObservableCollection()可以将其转换为可观测对象数据源。。。让我知道这是否解决了你的担忧。。。(对此,您仍然需要一个自定义的INotifyPropertyChnaged实现的分层类)是的,但您能否提供一个示例(代码),说明如何a)转换为可观察的数据源,以及b)将其加载到树视图中。插入代码时,不要使用某种HTML编码,而是使用此处提供的格式。嘿,Erno,当我第一次发布时,格式不起作用。。。我尝试插入的所有代码都是按照现在的方式来的。。。请检查!首先阅读文档以获取格式化代码:第二:当向编号序列添加代码时(正如您所做的),您需要缩进一个额外的级别(因此是8个空格的前缀)