绑定到数据集的WPF/XAML TreeView不会在父DataRow键改变时更新子节点/子项
本文关键字:改变 DataRow 子项 子节点 更新 数据集 WPF XAML TreeView 绑定 | 更新日期: 2023-09-27 18:13:25
重要的是:我来自德国-很抱歉我的英语可能很差:)
<标题>我的问题:我有一个TreeView,它被绑定到一个具有多个分层数据表的数据集(当然需要数据关系)。
当改变DataTable1中的PrimaryKey Column1的值时(见下面的节点'Test2'), TreeView更新了这个"根节点",但它的SubNodes消失/将被删除。
有趣的事实:当将DataTable1中的PrimaryKey Column1的值更改回旧值时,一切都很好(像以前一样)。
DataTable1中更改后的DataRow在DataTable2和DataTable3中的子DataRow成功地获得了新的键值。只有TreeView会"丢失"子节点。
之前的示例(作为树):
+Test1
-Test2
-Test2-1
Test2-1-1
Test2-1-2
-Test2-2
Test2-2-1
Test2-2-2
+Test3
+Test4
+Test5
之后的示例(作为树):
+Test1
Test2
+Test3
+Test4
+Test5
后台代码
public MainWindow()
{
InitializeComponent();
DataSet ds = new DataSet("DummyDS");
DataTable dt = new DataTable("DummyT1");
dt.Columns.Add(new DataColumn("DummyT1C1", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT1C2", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT1C3", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT1C4", typeof(string)));
dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };
ds.Tables.Add(dt);
dt = new DataTable("DummyT2");
dt.Columns.Add(new DataColumn("DummyT2C1", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT2C2", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT2C3", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT2C4", typeof(string)));
dt.PrimaryKey = new DataColumn[] { dt.Columns[0], dt.Columns[1] };
ds.Tables.Add(dt);
dt = new DataTable("DummyT3");
dt.Columns.Add(new DataColumn("DummyT3C1", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT3C2", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT3C3", typeof(string)));
dt.Columns.Add(new DataColumn("DummyT3C4", typeof(string)));
dt.PrimaryKey = new DataColumn[] { dt.Columns[0], dt.Columns[1], dt.Columns[2] };
ds.Tables.Add(dt);
ds.Relations.Add(
new DataRelation("DummyT1_DummyT2",
ds.Tables[0].Columns[0],
ds.Tables[1].Columns[0]));
ds.Relations.Add(
new DataRelation("DummyT2_DummyT3",
new DataColumn[] { ds.Tables[1].Columns[0], ds.Tables[1].Columns[1] },
new DataColumn[] { ds.Tables[2].Columns[0], ds.Tables[2].Columns[1] }));
sampleTV.DataContext = ds.Tables[0];
ds.Tables[0].Rows.Add("Test1", "Test11", "Test12", "Test13");
ds.Tables[0].Rows.Add("Test2", "Test21", "Test22", "Test23");
ds.Tables[0].Rows.Add("Test3", "Test31", "Test32", "Test33");
ds.Tables[0].Rows.Add("Test4", "Test41", "Test42", "Test43");
ds.Tables[0].Rows.Add("Test5", "Test51", "Test52", "Test53");
ds.Tables[1].Rows.Add("Test1", "Test1-1", "Test1-11", "Test1-12");
ds.Tables[1].Rows.Add("Test2", "Test2-1", "Test2-11", "Test2-12");
ds.Tables[1].Rows.Add("Test3", "Test3-1", "Test3-11", "Test3-12");
ds.Tables[1].Rows.Add("Test4", "Test4-1", "Test4-11", "Test4-12");
ds.Tables[1].Rows.Add("Test5", "Test5-1", "Test5-11", "Test5-12");
ds.Tables[1].Rows.Add("Test1", "Test1-2", "Test1-21", "Test1-22");
ds.Tables[1].Rows.Add("Test2", "Test2-2", "Test2-21", "Test2-22");
ds.Tables[1].Rows.Add("Test3", "Test3-2", "Test3-21", "Test3-22");
ds.Tables[1].Rows.Add("Test4", "Test4-2", "Test4-21", "Test4-22");
ds.Tables[1].Rows.Add("Test5", "Test5-2", "Test5-21", "Test5-22");
ds.Tables[2].Rows.Add("Test1", "Test1-1", "Test1-1-1", "Test1-1-11");
ds.Tables[2].Rows.Add("Test2", "Test2-1", "Test2-1-1", "Test2-1-11");
ds.Tables[2].Rows.Add("Test3", "Test3-1", "Test3-1-1", "Test3-1-11");
ds.Tables[2].Rows.Add("Test4", "Test4-1", "Test4-1-1", "Test4-1-11");
ds.Tables[2].Rows.Add("Test5", "Test5-1", "Test5-1-1", "Test5-1-11");
ds.Tables[2].Rows.Add("Test1", "Test1-2", "Test1-2-1", "Test1-2-11");
ds.Tables[2].Rows.Add("Test2", "Test2-2", "Test2-2-1", "Test2-2-11");
ds.Tables[2].Rows.Add("Test3", "Test3-2", "Test3-2-1", "Test3-2-11");
ds.Tables[2].Rows.Add("Test4", "Test4-2", "Test4-2-1", "Test4-2-11");
ds.Tables[2].Rows.Add("Test5", "Test5-2", "Test5-2-1", "Test5-2-11");
ds.Tables[2].Rows.Add("Test1", "Test1-1", "Test1-1-2", "Test1-1-21");
ds.Tables[2].Rows.Add("Test2", "Test2-1", "Test2-1-2", "Test2-1-21");
ds.Tables[2].Rows.Add("Test3", "Test3-1", "Test3-1-2", "Test3-1-21");
ds.Tables[2].Rows.Add("Test4", "Test4-1", "Test4-1-2", "Test4-1-21");
ds.Tables[2].Rows.Add("Test5", "Test5-1", "Test5-1-2", "Test5-1-21");
ds.Tables[2].Rows.Add("Test1", "Test1-2", "Test1-2-2", "Test1-2-21");
ds.Tables[2].Rows.Add("Test2", "Test2-2", "Test2-2-2", "Test2-2-21");
ds.Tables[2].Rows.Add("Test3", "Test3-2", "Test3-2-2", "Test3-2-21");
ds.Tables[2].Rows.Add("Test4", "Test4-2", "Test4-2-2", "Test4-2-21");
ds.Tables[2].Rows.Add("Test5", "Test5-2", "Test5-2-2", "Test5-2-21");
ds.AcceptChanges();
}
private void tvTestBtn_Click(object sender, RoutedEventArgs e)
{
DataTable dt = (DataTable) sampleTV.DataContext;
DataRow dr = dt.Rows.Find("Test2");
dr.BeginEdit();
dr.SetField(0, "Test2aaa");
dt.AcceptChanges();
dr.EndEdit();
}
ButtonClick事件用于在运行时更改PrimaryKey值。
XAML(位于窗口中)
<StackPanel>
<Button x:Name="tvTestBtn" Content="Test" Click="tvTestBtn_Click"/>
<TreeView x:Name="sampleTV" ItemsSource="{Binding DefaultView}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding DummyT1_DummyT2}">
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding DummyT2_DummyT3}">
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={local:ItemConverter}}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<TextBlock Text="{Binding Converter={local:ItemConverter}}"/>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<TextBlock Text="{Binding Converter={local:ItemConverter}}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
我已经遗漏了'local:ItemConverter'的源代码,因为我知道没有问题(花了很多时间调试;))
我已经尝试过的
我花了几个小时(也可能是几天)找一个人,他也有这个问题-但没有找到任何人/任何东西。
我做了什么:
- 使TreeView的可视化无效->没有帮助。
- 删除DataContext并重新分配它->没有帮助。
- 从TreeView中删除ItemsSource并重新分配->没有帮助。
- 从TreeViewItem中删除ItemsSource并重新分配它->没有帮助。
- 从TreeView中删除ItemsTemplate并重新分配它->没有帮助。
- 从TreeView中删除ItemsSource,删除所有项目并重新分配->没有帮助。
所以我最后的希望是把我自己的问题贴在这里,因为我没有更多的想法。
在我看来,TreeView本身仍然"玩"旧数据(相对于DataRow的孩子),所以也许它只需要刷新-但如何?
任何帮助都太好了。:)
谢谢。
标题>你试过这样做吗?
// You'll have to have the DataSet ds as a field on class MainWindow:
DataSet ds = new DataSet("DummyDS");
private void tvTestBtn_Click(object sender, RoutedEventArgs e)
{
DataTable dt = (DataTable)sampleTV.DataContext;
DataRow dr = dt.Rows.Find("Test2");
dr.BeginEdit();
dr.SetField(0, "Test2aaa");
// Removes the old relation..
ds.Relations.Remove("DummyT1_DummyT2");
// and add it again
ds.Relations.Add(
new DataRelation("DummyT1_DummyT2",
ds.Tables[0].Columns[0],
ds.Tables[1].Columns[0]));
dt.AcceptChanges();
dr.EndEdit();
}
我不确定这是正确的方式,但如果它工作…
我认为当您更改其中一个键的值时,关系将失效。当键'Test2'更改为'Test2aaa'时,表2中的子元素不再与它相关??