如果父DataRow密钥更改

时间:2016-10-16 13:19:18

标签: c# wpf xaml binding treeview

首先要做的事情是:我来自德国 - 对于我可能不好的英语感到抱歉:)

我的问题:

我有一个TreeView,它绑定到一个具有多个分层DataTable的DataSet(当然还有所需的DataRelations)。

当更改DataTable1中的PrimaryKey Column1的值时(参见下面的节点' Test2'),TreeView会更新这个"根节点"但它的子节点消失/将被删除。

有趣的事实:当将DataTable1中的PrimaryKey Column1的值更改回旧值时,一切都很好(就像之前一样)。

DataTable1中DataWable2和DataTable3中的子DataRows成功获得了新的键值。 只有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>

我遗漏了本地的来源:ItemConverter&#39;因为我知道没有问题(花了很多时间调试;))

我已经尝试了什么

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

我做了什么:

  1. 使TreeView的视觉无效 - &gt;没有帮助。
  2. 删除DataContext并重新分配它 - &gt;没有帮助。
  3. 从TreeView中删除ItemsSource并重新分配它 - &gt;没有帮助。
  4. 从TreeViewItem中删除ItemsSource并重新分配它 - &gt;没有帮助。
  5. 从TreeView中删除ItemsTemplate并重新分配它 - &gt;没有帮助。
  6. 从TreeView中删除ItemsSource,删除所有项目并重新分配 - &gt;没有帮助。
  7. 所以我最后的一线希望是在这里发表我自己的问题,因为我没有更多的想法。

    IMO TreeView本身仍在播放&#39;使用旧数据(与DataRow的子项相关),也许它只需要刷新 - 但是如何?

    任何帮助都会很棒。 :)

    感谢。

1 个答案:

答案 0 :(得分:0)

你有没有试过这样的事情:

// 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中的子元素不再与之相关吗??