使用TreeView和Popup控件的WPF问题

时间:2009-08-07 16:26:38

标签: wpf xaml treeview popup

在WPF中的TreeView中使用Popup时,我遇到弹出窗口内的控件无法使用的问题。例如,使用以下代码,弹出窗口内的ToggleButton只能切换一次,然后无法切换回来。有没有办法解决这个问题?

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <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>

4 个答案:

答案 0 :(得分:3)

问题是您将Popup嵌入 TreeViewItem 中,并且以某种方式干扰了其内置功能。无论如何,我不认为Popups会以这种方式使用。因为您可以指定Popup的 PlacementTarget ,所以您可以在任何地方声明它们,然后在您想要的位置打开它们。以下标记用您的示例演示了这一点:

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

如您所见,Popup可以在任何地方声明。然后,您可以使用PlacementTarget将其放在您想要的位置。通过此更改,ToggleButton按预期工作。

答案 1 :(得分:1)

感谢Charlie发现使用TreeView的问题......

将树视图上的Focusable设置为false似乎也有效。但可能会引起其他问题。

<TreeView Focusable="False">

从我可以看出的问题是哪个控件正在关注焦点,所以看起来你的树视图正在关注鼠标点击而不是按钮。

答案 2 :(得分:1)

在与WPF团队讨论后,我发现这只是WPF的一个问题。

对于我的情况,我试图创建一个用于每个TreeViewItem的放置对话框。我玩了不同的控件试图获得我需要的外观,我发现ComboBox的Popup部分在TreeView中运行良好。

因此我最终在TreeView中使用了一个ComboBox,并强制ComboBox只有一个始终被选中的项目,该项目将是我的drop对话框。在此之后,我只需要将ComboBox设计为与我需要的外观相匹配。下面的代码显示了我所做的一般想法。

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

答案 3 :(得分:0)

我遇到了同样的问题,其中树视图使用数据模板和多个用户控件显示分层项目,其中一个用户控件是一个弹出窗口的切换按钮。

这会完全冻结,根本不会回应。该问题与Focus属性有关,但将Focusable设置为 false 并不总是有效。

通过查看上面提供的解决方案,我喜欢在treeviewitem中使用组合框的最后一个。但它又导致了一个问题。每当用户选择组合框的(单个)项时,它将在组合框中显示为selectedValue,我只想表现得像弹出的切换。

我还想将组合框上的三角形更改为省略号。所以我通过更改控件模板尝试了这个解决方案。

这是我的解决方案:

                                                                                                                                                                                                                                                                                                                                                                                                                                           ...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ...                                                                                                                                                                                                                                                                                                                             

    <Style x:Key="ComboBoxStyle1" TargetType="{x:Type ComboBox}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource ComboBoxFocusVisual}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
        <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="Padding" Value="4,3"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid x:Name="MainGrid" SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Popup x:Name="PART_Popup" Margin="1" 
                               AllowsTransparency="true" 
                               IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" 
                               Placement="Bottom" 
                               PopupAnimation="Fade">
                            <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}" Color="Transparent">
                                <Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="2" CornerRadius="0,4,4,4">
                                    <ScrollViewer CanContentScroll="true">
                                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/>
                                    </ScrollViewer>
                                </Border>
                            </Microsoft_Windows_Themes:SystemDropShadowChrome>
                        </Popup>
                        <ToggleButton Style="{StaticResource ComboBoxReadonlyToggleButton}" 
                                      Background="{TemplateBinding Background}" 
                                      BorderBrush="{TemplateBinding BorderBrush}" 
                                      IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
                            <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
                            <Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
                        </Trigger>
                        <Trigger Property="HasItems" Value="false">
                            <Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            <Setter Property="Background" Value="#FFF4F4F4"/>
                        </Trigger>
                        <Trigger Property="IsGrouping" Value="true">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsEditable" Value="true">
                <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
                <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
                <Setter Property="IsTabStop" Value="false"/>
                <Setter Property="Padding" Value="3"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="ComboBoxItemStyle1" TargetType="{x:Type ComboBoxItem}">
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Padding" Value="3,0,3,0"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                    <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsHighlighted" Value="true">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<TreeView >
    <TreeViewItem IsExpanded="True">
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top"
                  IsEditable="False"
                  Style="{StaticResource ComboBoxStyle1}">
            <ComboBox.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
            </ComboBox.Resources>
            <ComboBoxItem IsSelected="False">
                <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>