views:

824

answers:

4

When using a Popup inside a TreeView in WPF I am running into an issue where the controls inside the popup become unusable. For example, using the following code the ToggleButton inside the popup can only be toggled once and then becomes unable to be toggled back. Is there any way to work around this issue?

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Grid>
        <TreeView>
            <TreeViewItem>
                <TreeViewItem.Header>
                    <StackPanel>
                        <ToggleButton>
                            Button outside popup
                        </ToggleButton>
                        <Popup IsOpen="True">
                            <ToggleButton>
                                Button inside popup
                            </ToggleButton>
                        </Popup>
                    </StackPanel>
                </TreeViewItem.Header>
            </TreeViewItem>
        </TreeView>
    </Grid>   
</Page>
+3  A: 

The problem is that you are embedding the Popup inside the TreeViewItem, and somehow that is interfering with its built-in functionality. I don't think Popups are meant to be used that way, anyway. Because you can specify the PlacementTarget of a Popup, you can declare them anywhere and then open them at the location you want. The following mark-up demonstrates this with your example:

<StackPanel>
  <Popup IsOpen="True" PlacementTarget="{Binding ElementName=buttonPanel}"
         Placement="Bottom">
    <ToggleButton>
      Button inside popup
    </ToggleButton>
  </Popup>
  <TreeView>
    <TreeViewItem>
      <TreeViewItem.Header>
        <StackPanel Name="buttonPanel">
          <ToggleButton>
            Button outside popup
          </ToggleButton>
        </StackPanel>
      </TreeViewItem.Header>
    </TreeViewItem>
  </TreeView>
</StackPanel>

As you can see, the Popup can be declared anywhere. You can then use PlacementTarget to put it right where you want. With this change, the ToggleButton works as expected.

Charlie
I agree that in the simple case presented here this solution would work, but for my actual senario I am using a user control in a HierarchicalDataTemplate to define the TreeViewItem header and this user control has a popup in it and I am getting the same behavior as the simple senario presented here. Because of this using the PlacementTaget and declaring the Popup outside of the TreeView won't work for me.
dlannoye
And you have to place it in the TreeViewItem.Header? Are you sure you can't place it in the UserControl.Resources or anywhere else?
Charlie
This might work but it is far from ideal. The control I want to host inside the TreeViewItem is similar to a ComboBox, but can't be created using a ComboBox and I am using the Popup to be used like the drop down portion of the combobox. Because of this I would like to keep the Popup in a single user control with the other TreeViewItem content. There must be some way around this issue because from the ComboBox control template I can see it is using a popup and it can be used in a TreeViewItem with no issues.
dlannoye
Perhaps you could post the code you are using, rather than the simplified scenario. I can't quite wrap my head around what you are trying to do that makes this solution unfeasible.
Charlie
+1  A: 

Thanks to Charlie finding the issue with using TreeView...

Setting Focusable on the tree view to false also seems to work. But may cause you other issues.

<TreeView Focusable="False">

From what I can tell the issue is which control is taking focus, so it looks like your treeview is taking focus of the mouse click instead of the button.

Chris Persichetti
Thanks for the suggestion, but setting the TreeView to not be focusable means that it will not be able to be navigated using the keyboard.
dlannoye
A: 

Hi, I ended up with the same problem and found your post, i tried as well many things but no good solution for it.

Did you find a workaround for this problem ?

thanks in advance

mourad
I have added an answer explaining what I did. It worked for my scenario, but it is not a general solution for the problems with TreeViews and Popups.
dlannoye
A: 

After discussion with the WPF team I found out that is this is just an issue with WPF.

For my case I was trying to create a drop dialog that is used for each TreeViewItem. I played around with different controls trying to get the looked I needed and I discovered that the Popup portion of a ComboBox worked fine inside a TreeView.

Because of this I ended up using a ComboBox inside the TreeView and forcing the ComboBox to only have one item that is always selected and that item would be my drop dialog. After this I just needed to style the ComboBox to match the look I needed. The code below shows the general idea of what I did.

<TreeView>
    <TreeViewItem>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top">
            <ComboBox.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
            </ComboBox.Resources>
            <ComboBoxItem IsSelected="True">
                <StackPanel Orientation="Vertical">
                    <Label>Some stuff on the combobox popup</Label>
                    <RadioButton>Radio Button 1</RadioButton>
                    <RadioButton>Radio Button 2</RadioButton>
                    <CheckBox>Check Box</CheckBox>
                    <Button HorizontalAlignment="Right">Ok</Button>
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>
    </TreeViewItem>
</TreeView>
dlannoye