4

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.

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;


    }
user589195
  • 4,180
  • 13
  • 53
  • 81
  • Is it something to do with event bubbling? I'll try setting e.handled = true; in the child selected handler – user589195 Nov 13 '12 at 11:04

3 Answers3

7

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.

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 Handled value to true of the RoutedEventArgs parameter.

EDIT:

Here's the XAML I used:

<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 = true statement is left commented then Parent_Selected will fire when the child object is selected.

Spencer Ruport
  • 34,865
  • 12
  • 85
  • 147
  • I've added the code in my event handlers. I really cant see why its doing this. It after stepping through the child selected event the window pops back up again for a fractions of a second then drops into the parent selected event. – user589195 Nov 13 '12 at 11:24
  • I tried the e.handled and it STILL fires the parent event handler :( Seems to raise a new RoutedEventArgs with handled = false in teh parent handler. – user589195 Nov 13 '12 at 11:30
  • Hm, well that part is a problem. Can you post the code you use to populate the treeview control? – Spencer Ruport Nov 13 '12 at 11:31
  • Diagnosed problem. posted answer. Thanks for your help matey :) Thought I was going insane. – user589195 Nov 13 '12 at 11:39
0

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?

user589195
  • 4,180
  • 13
  • 53
  • 81
0

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.)

A related question (and answer) is here: 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).

Community
  • 1
  • 1