绑定到数据集的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'的源代码,因为我知道没有问题(花了很多时间调试;))

我已经尝试过的

我花了几个小时(也可能是几天)找一个人,他也有这个问题-但没有找到任何人/任何东西。

我做了什么:

  1. 使TreeView的可视化无效->没有帮助。
  2. 删除DataContext并重新分配它->没有帮助。
  3. 从TreeView中删除ItemsSource并重新分配->没有帮助。
  4. 从TreeViewItem中删除ItemsSource并重新分配它->没有帮助。
  5. 从TreeView中删除ItemsTemplate并重新分配它->没有帮助。
  6. 从TreeView中删除ItemsSource,删除所有项目并重新分配->没有帮助。

所以我最后的希望是把我自己的问题贴在这里,因为我没有更多的想法。

在我看来,TreeView本身仍然"玩"旧数据(相对于DataRow的孩子),所以也许它只需要刷新-但如何?

任何帮助都太好了。:)

谢谢。

绑定到数据集的WPF/XAML 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中的子元素不再与它相关??