选择子项后触发 WPF TreeviewItem 父选择事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13359617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF TreeviewItem parent selected event fired after selecting a child?
提问by user589195
I have a standard WPF treeview item with a number of children. When creating the tree programatically I add selected event handlers to the parent and children items. What I am finding is that when after the child items selected event has fired and being handled, the parents event is then fired. The problem with this is that I populate a datagrid based on the selected item. So everytime after selecting a child item the datagrid is reset to the parent item selection.
我有一个带有多个子项的标准 WPF 树视图项。以编程方式创建树时,我将选定的事件处理程序添加到父项和子项。我发现的是,当子项选择的事件被触发并被处理后,父事件就会被触发。问题是我根据所选项目填充数据网格。因此,每次选择子项后,数据网格都会重置为父项选择。
Please could someone explain if this item is normal or if I'd doing something wrong and how to fix it.
请有人解释这个项目是否正常,或者我是否做错了什么以及如何解决它。
Please let me know if you require anymore information.
如果您需要更多信息,请告诉我。
Hooking up event handlers:
连接事件处理程序:
//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;
Handlers:
处理程序:
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;
}
回答by Spencer Ruport
This has to be something with your code. I'm using a TreeView right now and child selection doesn't trigger parent selection for me. Can you post more of your code? Perhaps I can spot the issue.
这必须与您的代码有关。我现在正在使用 TreeView 并且子选择不会为我触发父选择。你能发布更多你的代码吗?也许我能发现问题所在。
I stand corrected. After looking through my code a bit more and running some tests it appears this is normal behavior for the control. If you don't want selections to bubble up then yes you should set the Handledvalue to trueof the RoutedEventArgsparameter.
我站着纠正。在仔细查看我的代码并运行一些测试后,这似乎是控件的正常行为。如果你不想选择冒泡然后是你应该设定Handled值true的的RoutedEventArgs参数。
EDIT:
编辑:
Here's the XAML I used:
这是我使用的 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>
And the code:
和代码:
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;
}
If the e.Handled = truestatement is left commented then Parent_Selectedwillfire when the child object is selected.
如果该e.Handled = true语句被留下注释,Parent_Selected则将在选择子对象时触发。
回答by user589195
Well I found my problem.
好吧,我发现了我的问题。
The issue only presents itself when I have a breakpoint set in the child selected event handler. With no breakpoints set everything works fine and the datagrid is populated as if the child item was selected. With only a break point set in the parent selected event the breakpoint isnt fired when selecting a child. But as soon as I add a break point in the child item, the breakpoint in the parent selected handler is fired straight after.
该问题仅在我在子选定事件处理程序中设置断点时才会出现。没有设置断点,一切正常,数据网格被填充,就像选择了子项一样。仅在父选定事件中设置断点,选择子项时不会触发断点。但是,只要我在子项中添加断点,父选定处理程序中的断点就会立即触发。
Can anyone explain this or is it just a bug is Visual Studio?
任何人都可以解释这一点,还是只是 Visual Studio 的一个错误?
回答by wljiang
The problem of a parent treenode getting selected aftering clicking onto a child treenode can have another possible reason: If in treeview's selection changed event handler, the Focus is changed onto other control than the treeview itself (for example, calling another control's Focus() function), it will cause the treeview to raise another selection changed event after the current event, which will set parent as selected. (To make the debugging even harder, the visual studio call stack window does not tell which routine triggered this event.)
单击子树节点后父树节点被选中的问题可能有另一个可能的原因:如果在树视图的选择更改事件处理程序中,焦点被更改到树视图本身以外的其他控件上(例如,调用另一个控件的 Focus() 函数),它会导致树视图在当前事件之后引发另一个选择更改事件,这会将父级设置为选中状态。(为了使调试更加困难,visual studio 调用堆栈窗口不会告诉哪个例程触发了此事件。)
A related question (and answer) is here: TreeView auto-selecting parent after user selects child
一个相关的问题(和答案)在这里:TreeView auto-selecting parent after user selects child
May not be the reason of this question, but posted here just in case someone gets driven crazy by this "strange" problem (like what I just suffered).
可能不是这个问题的原因,但张贴在这里以防万一有人被这个“奇怪”的问题逼疯(就像我刚刚遭受的)。

