Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TreeView in Flyout, selection after Flyout closes #49

Open
ivansp opened this issue Dec 25, 2017 · 3 comments
Open

TreeView in Flyout, selection after Flyout closes #49

ivansp opened this issue Dec 25, 2017 · 3 comments

Comments

@ivansp
Copy link

ivansp commented Dec 25, 2017

I am currently trying to use WinRT xaml ToolKit TreeView component since it is not supported in UWP natively.

TreeView is inside a button Flyout. When I press the button I want Flyout to appear so I can select an item from the tree. And I bind a command from ViewModel to SelectedItemChanged event:

<Button
   x:Name="btnFilter"
   HorizontalAlignment="Right"
   Command="{Binding OpenFiltersCommand}"
   Style="{StaticResource SecondaryMenuButtonStyle}">
   <StackPanel Orientation="Horizontal">
     <Image
       Width="28"
       Margin="0,0,4,0"
       Source="{StaticResource FilterIcon}" />
     <TextBlock x:Uid="Filter" Style="{StaticResource GrayTextBlockStyle}" />
   </StackPanel>
   <FlyoutBase.AttachedFlyout>
     <controls1:CustomFlyout IsOpen="{Binding IsFiltersOpen, Mode=TwoWay}" Parent="{Binding ElementName=btnFilter}">
        <controls2:TreeView
          ItemContainerStyle="{StaticResource DefaultTreeViewItem}"
          ItemTemplate="{StaticResource TreeViewItemTemplate}"
          ItemsSource="{Binding BuildingTree}"
          Style="{StaticResource DefaultTreeViewStyle}">
            <i:Interaction.Behaviors>
              <core:EventTriggerBehavior EventName="SelectedItemChanged">
                <core:InvokeCommandAction Command="{Binding ChangeRoomCommand}" />
              </core:EventTriggerBehavior>
            </i:Interaction.Behaviors>
         </controls2:TreeView>
      </controls1:CustomFlyout>
   </FlyoutBase.AttachedFlyout>
</Button>

After I select an item from TreeView, SelectedItemChanged event fires as it should, but afterwards I close the Flyout and the event fires again. The second time it usually fires saying new selected element is next after current's parent. So for example if I have this structure:


1
--1.0
--1.1
--1.2
2
--2.0
--2.1

So if I select --1.1 first SelectedItemChanged will fire with --1.1 element, and afterwards it will fire with 2 as new selected item.

Note: I am using CustomFlyout component which I can close from ViewModel, but I also tested this with regular Flyout and same thing happens after I close Flyout by clicking outside of it.

UPDATE: I've downloaded WinRT code and started debugging the TreeView component locally. In TreeViewItem.cs I've found the source of the problem in this function:

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            // Since the GotFocus event will bubble up to the parent
            // TreeViewItem (which will make it think it's also selected), it
            // needs to ignore that event when it's first been handled by one of
            // its nested children.  We use the IgnoreNextGotFocus flag to
            // notify our parent that GotFocus has already been handled.
            TreeViewItem parent = ParentTreeViewItem;
            if (parent != null)
            {
                parent.CancelGotFocusBubble = true;
            }

            try
            {
                if (Interaction.AllowGotFocus(e) && !CancelGotFocusBubble)
                {
                    // Select the item when it's focused
                    Select(true);

                    // ActivateAsync the selection
                    IsSelectionActive = true;
                    UpdateVisualState(true);

                    Interaction.OnGotFocusBase();
                    base.OnGotFocus(e);
                }
            }
            finally
            {
                CancelGotFocusBubble = false;
            }            
        }

From what I can tell when element gets focus sometimes it fails to find it's parent and prevent propagating the event upwards in the tree.

Can anyone help me out with this issue?

@xyzzer
Copy link
Owner

xyzzer commented Dec 27, 2017

Seems like you posted a workaround on SO: https://stackoverflow.com/questions/47968536/uwp-winrt-xaml-toolkit-treeview-in-flyout-changes-selection-after-flyout-clos/47976018#47976018

As I said previously it seems this is a bug in WinRT TreeView component however I managed to prevent (hard fix) this behavior by binding "IsEnabled" property to IsFiltersOpen property from my ViewModel.
This way when I select my element I close the Flyout and disable TreeView component, which prevents it from updating.

@ivansp
Copy link
Author

ivansp commented Dec 27, 2017

Yep sorry for late reply, wasn't sure if anyone was still checking issues on here. But yes, I inspected TreeView component locally and realized it was checking for IsEnabled property when updating selection so I binded that property to view models's IsFlyoutOpen.

Seems to solve the issue for my use case. Still it's kind of a "hard-fix" if you will.

@xyzzer
Copy link
Owner

xyzzer commented Dec 27, 2017

A workaround is better than nothing and sometimes it's even better than a fix if the fix introduces new bugs... ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants