WPF TreeviewItem选中子项后,父级是否触发选中事件?

5
我有一个标准的WPF树形视图项,其中包含许多子项。当以编程方式创建树时,我为父项和子项添加了选定事件处理程序。我发现的问题是,在子项的选定事件已经被触发并处理后,然后再触发父项的事件。这个问题的困扰在于,我根据所选项目填充数据网格。因此,每次选择子项后,数据网格都会重置为父项的选择。
请问这种情况是否正常,或者我做错了什么以及如何解决它呢?如果需要更多信息,请告诉我。
挂接事件处理程序:
//parent
TreeViewItem tvi = new TreeViewItem();

                    tvi.Header = str;

                    tvi.Selected += CoreSupplierSelected

//child
TreeViewItem tvi = new TreeViewItem();
                            tvi.Header = str;
                            tvi.Tag = resinSystems.Values[i];
                            tvi.Selected += CoreResinSystemSelected;

处理程序:

private void CoreSupplierSelected(object sender, RoutedEventArgs e)
    {
        TreeViewItem item = e.OriginalSource as TreeViewItem;
        MaterialSelectionData thicknessData = editInterface.GetCoreThicknessData(new List<object>() { item.Tag }, null);
        List<string> columnNames = thicknessData.DisplayFieldTitles;
        columnNames.Insert(0,"");
        DataTable dt = GUICommon.DatableConverter.ToDataTable(thicknessData.DisplayData, columnNames);
        dtgCores.ItemsSource = dt.AsDataView();
        dtgCores.Columns[0].Visibility = System.Windows.Visibility.Collapsed;
    }

    private void CoreResinSystemSelected(object sender, RoutedEventArgs e)
    {

        TreeViewItem item = e.OriginalSource as TreeViewItem;
        GX3MaterialSelectionData thicknessData = editInterface.GetCoreThicknessData(new List<object>() { ((TreeViewItem)item.Parent).Tag }, new List<object>() { item.Tag });
        List<string> columnNames = thicknessData.DisplayFieldTitles;
        columnNames.Insert(0, "");
        DataTable dt = GUICommon.DatableConverter.ToDataTable(thicknessData.DisplayData, columnNames);
        dtgCores.ItemsSource = dt.AsDataView();
        e.Handled = true;
        dtgCores.Columns[0].Visibility = System.Windows.Visibility.Collapsed;


    }

这与事件冒泡有关吗?我将在子选择处理程序中尝试设置e.handled = true; - user589195
3个回答

7
这可能与您的代码有关。我现在正在使用一个TreeView,子选择不会触发父选择。您能发布更多代码吗?也许我可以找到问题所在。
我错了。经过对我的代码进行进一步查看和运行一些测试后,发现这是控件的正常行为。如果您不希望选择向上传播,那么是的,您应该将参数的值设置为。
编辑:
这是我使用的XAML:
<TreeView Width="200" Height="300">
    <TreeViewItem Header="Parent" Selected="Parent_Selected">
        <TreeViewItem Header="Child" Selected="Child_Selected" />
    </TreeViewItem>
    <TreeViewItem Header="Parent" Selected="Parent_Selected">
        <TreeViewItem Header="Child" Selected="Child_Selected" />
    </TreeViewItem>
</TreeView>

以下是代码:

private void Parent_Selected(object sender, RoutedEventArgs e)
{
    bool test = false;
}

private void Child_Selected(object sender, RoutedEventArgs e)
{
    bool test = false;
    // e.Handled = true;
}

如果将e.Handled = true语句保留为注释状态,则当选择子对象时,Parent_Selected仍然会触发。

我已经在我的事件处理程序中添加了代码。我真的看不出它为什么会这样做。在步进子选择事件之后,窗口会再次弹出一小段时间,然后进入父选择事件。 - user589195
我尝试了e.handled,但它仍然触发了父事件处理程序 :( 在父处理程序中似乎引发了一个handled = false的新RoutedEventArgs。 - user589195
嗯,那部分有问题。你能发一下用来填充树形控件的代码吗? - Spencer Ruport
诊断出问题,发布了答案。谢谢你的帮助,伙计:) 以为我要疯了。 - user589195

0
一个父节点在点击子节点后被选中的问题可能有另外一个原因:如果在树形视图的选择更改事件处理程序中,焦点被改变到除树形视图本身之外的其他控件上(例如调用另一个控件的Focus()函数),它将导致树形视图在当前事件之后引发另一个选择更改事件,这将把父节点设置为选定状态。(为了使调试更加困难,Visual Studio调用堆栈窗口不会告诉您是哪个例程触发了此事件。)
相关问题(和答案)在这里:TreeView auto-selecting parent after user selects child 也许不是这个问题的原因,但在这里发布以防万一有人被这个“奇怪”的问题搞疯了(就像我刚才遭受的那样)。

0

我找到了问题所在。

只有在子选择事件处理程序中设置断点时,才会出现此问题。如果没有设置断点,则一切正常,数据网格将填充,就好像选择了子项。 只有在父选择事件中设置断点时,当选择子项时,断点不会触发。 但是,一旦我在子项中添加断点,父选择处理程序中的断点立即触发。

有人能解释这是为什么吗?还是这只是Visual Studio中的一个错误?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接