如何在WPF用户控件中使用动态数据集替换静态XmlDataProvider的正确方法?

5

由于我认为我可能不知道最好的方法,因此可能需要编辑问题。

我的WPF用户控件当前的配置如下。 我有一个XmlDataProvider,其中包含一些静态XML元素,我使用它们来填充TreeView控件。 我目前使用HierarchicalDataTemplate来绑定到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}" 

我希望能在运行时从xml文件中加载数据来替换当前的静态资源。此外,我希望用户能够在运行时修改树形视图的节点,并将这些值写回同一xml文件。我一直在研究使用MVVM模式和创建IObservable类。有人可以指点我吗?
编辑: 也许我的问题表述不太好。有人能推荐改进或进行任何提高问题质量的编辑吗?

你有没有想过如何做到这一点? - czuroski
@czuroski,不好意思我没有。我一直在忙另一个项目,但仍在寻找答案。 - Anonymous Type
1
@czuroski,不幸的是,在 .net 中代表 Xml 的 API XmlDocument 不可观察...你唯一能访问它的方式是使用这段代码...((XmlDataProvider)this.FindResource("SharePointSites")).Document.SelectNodes("myroot")...好消息是这是一个 ICollection,所以使用 LINQ、.ToList() 和 new ObservableCollection<T>(<List>) 你可以将其转换为可观察对象数据源...如果这解决了你的问题,请告诉我...(你仍然需要一个自定义的实现层次结构的 INotifyPropertyChanged) - WPF-it
可以提供一个示例(代码)来说明如何a)转换为可观察数据源,以及b)将其加载到树视图中吗? - Anonymous Type
1个回答

3

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

假设您的Xml结构如下...

<MyItem Name="Root"> 
    <MyItem Name="ABC"/> 
    <MyItem Name="PQR"> 
        <MyItem Name="IJK"/> 
    </MyItem> 
    <MyItem Name="XYZ"/> 
</MyItem> 
  1. Bind your ItemsSource thru a converter , say MyXmlToObjectDataSourceConverter.

    <TreeView ItemsSource="{Binding Source={StaticResource SharePointSites},
           Converter={StaticResource MyXmlToObjectDataSourceConverter}}" ... />
    
  2. In MyXmlToObjectDataSourceConverter.Convert() method return this...

    public object Convert(...) 
    { 
        return new ObservableCollection<XmlNodeWrapper>(
            ((XmlDataProvider)value).Document.SelectNodes("MyItem").Select( 
                d => new XmlNodeWrapper(d)).ToList()) 
    }
    
  3. XmlNodeWrapper class will maintain the 'node' internally so that when updates take place thru property Setters, you can update the node based attribute back... like this...

    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)); 
            } 
        }
    } 
    
  4. Then replace all XPath attributes in your XAML with standard Path.

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

在插入代码时,请勿使用某种HTML编码,而是使用此处提供的格式。 - Emond
嗨Erno,第一次发布时格式不起作用...我尝试插入的所有代码都是现在这样的...请检查! - WPF-it
1
  1. 首先阅读格式化代码的文档:http://stackoverflow.com/editing-help#syntax-highlighting
  2. 当向数字序列添加代码时(就像您所做的那样),您需要多缩进一级(因此为8个空格前缀)。
- Emond

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