如果有人有興趣,這是我想出了:
的XAML:
<Window.Resources>
<local:NodeAvailableConverter x:Key="MyConverter"/>
<XmlDataProvider x:Key="xmlsource">
<x:XData>
<main xmlns="">
<sub/>
</main>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<DockPanel DataContext="{Binding Source={StaticResource xmlsource}}">
<CheckBox Content="CheckBox1" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added1"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<CheckBox Content="CheckBox2" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added2"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<Label Content="{Binding OuterXml}" />
</DockPanel>
行爲:
[ContentProperty("CustomNode")]
public class MyBehavior : Behavior<CheckBox>
{
protected override void OnAttached()
{
base.OnAttached();
binding = new Binding();
binding.XPath = XPath + "/" + CustomNode.Name;
binding.Mode = BindingMode.OneWay;
binding.Converter = NodeAvailableConverter.Instance;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
AssociatedObject.Click += new RoutedEventHandler(AssociatedObject_Click);
SourceProv.Refresh();
}
void AssociatedObject_Click(object sender, RoutedEventArgs e)
{
var parent = SourceProv.Document.SelectSingleNode(XPath);
if(AssociatedObject.IsChecked==true)
{
var newelement = SourceProv.Document.CreateElement(CustomNode.Name);
foreach (var at in CustomNode.Attributes)
newelement.SetAttribute(at.Name, at.Value);
parent.AppendChild(newelement);
}
else if (AssociatedObject.IsChecked == false)
parent.RemoveChild(parent.SelectSingleNode(CustomNode.Name));
SourceProv.Refresh();
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
}
public XmlDataProvider SourceProv { get; set; }
public Node CustomNode { get; set; }
public String XPath { get; set; }
private Binding binding { get; set; }
}
public class NodeAvailableConverter : IValueConverter
{
private static NodeAvailableConverter _instance;
public static NodeAvailableConverter Instance
{
get
{
if (_instance == null)
_instance = new NodeAvailableConverter();
return _instance;
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
[ContentProperty("Attributes")]
public class Node
{
public string Name { get; set; }
private List<Attribute> _attributes;
public List<Attribute> Attributes { get
{
if (_attributes == null)
_attributes = new List<Attribute>();
return _attributes;
} }
}
public class Attribute
{
public string Name { get; set; }
public string Value { get; set; }
}
現在這整個事情看起來並不好看完全可以完成工作。 不過這到是揭示一些奇怪的行爲:
的結合,似乎每一個(我爲什麼要再次每次也就那麼多了)
XmlDataProvider的刷新方法是點擊事件被觸發時被取消設置在Clickhandler執行之前調用一次,就像Refresh第一次執行時一樣,它將原始XmlDocument拉回到XmlDataProvider並關閉當前的XmlDocument。
非常尷尬......如果任何人都可以清理任何東西,非常感謝。