问题可能需要编辑,因为我认为我不一定知道最好的方法。
WPF用户控件的当前配置。我有一个XmlDataProvider,其中包含一些用于填充TreeView控件的静态XML元素。我目前使用一个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控件 <TreeView ItemsSource="{Binding Source={StaticResource SharePointSites}}"
ItemTemplate="{StaticResource SiteTemplate}"
我想用在运行时从xml文件加载的数据替换当前的静态资源。此外,我希望用户能够在运行时修改treeview的节点,并将这些值写回相同的xml文件。我一直在阅读有关使用MVVM模式和创建IObservable类的内容。有人能给我指个正确的方向吗?
编辑:也许我问这个问题的方式不太理想。谁能建议改进或编辑以提高问题的质量?
我无法访问我的Visual Studio环境,所以下面的代码将充满编译错误…因此,请将此视为伪代码…
假设Xml结构是这样的....
<MyItem Name="Root">
<MyItem Name="ABC"/>
<MyItem Name="PQR">
<MyItem Name="IJK"/>
</MyItem>
<MyItem Name="XYZ"/>
</MyItem>
绑定你的ItemsSource通过一个转换器,说myxmltobjectdatasourcececonverter。
<TreeView ItemsSource="{Binding Source={StaticResource SharePointSites}, Converter={StaticResource MyXmlToObjectDataSourceConverter}}" ... />
在myxmltobjectdatasourcececonverter . convert()方法中返回这个…
public object Convert(...) { return new ObservableCollection<XmlNodeWrapper>( ((XmlDataProvider)value).Document.SelectNodes("MyItem").Select( d => new XmlNodeWrapper(d)).ToList()) }
XmlNodeWrapper类将在内部维护'node',以便当通过属性设置器进行更新时,您可以将基于节点的属性更新回来…像这样…
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)); } } }
然后用标准的Path替换XAML中的所有XPath属性。
<HierarchicalDataTemplate x:Key="SiteTemplate" ItemsSource="{Binding Path=Children}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate>