2009-08-07 98 views
3

当在WPF中的TreeView中使用弹出窗口时,我遇到了弹出窗口中的控件变得不可用的问题。例如,使用以下代码,弹出窗口中的ToggleButton只能切换一次,然后无法切换回来。有什么办法可以解决这个问题吗?WPF问题与TreeView和弹出控件

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

回答

3

的问题是,你是嵌入树型视图内弹出,并以某种方式被其内置的功能干扰。无论如何,我不认为弹出窗口是以这种方式使用的。因为您可以指定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按预期工作。

+0

我同意,在这里介绍的简单的情况下,该解决方案将工作,但我的实际塞纳里奥我使用的是用户控制在HierarchicalDataTemplate定义TreeViewItem头和这个用户控件有一个弹出窗口,并且我得到了与这里提供的简单的Senario相同的行为。因为使用PlacementTaget并在TreeView之外声明Popup对我不起作用。 – dlannoye 2009-08-07 18:16:03

+0

你必须把它放在TreeViewItem.Header中?你确定你不能把它放在UserControl.Resources或其他地方吗? – Charlie 2009-08-07 19:09:29

+0

这可能会奏效,但它远非理想。我想要在TreeViewItem中托管的控件类似于ComboBox,但不能使用ComboBox创建,我使用的Popup像组合框​​的下拉部分一样使用。正因为如此,我想将Popup与其他TreeViewItem内容保存在一个用户控件中。必须有一些解决此问题的方法,因为从ComboBox控件模板中我可以看到它使用弹出窗口,并且可以在TreeViewItem中使用而不会出现问题。 – dlannoye 2009-08-13 22:39:15

1

感谢查理发现这个问题用的TreeView ...

树视图设置可聚焦于假也似乎工作。但可能会导致你其他问题。

<TreeView Focusable="False"> 

从我可以告诉的问题是控制正在专注,所以它看起来像你的TreeView走的是鼠标点击,而不是按钮的焦点。

+1

感谢您的建议,但将TreeView设置为不可聚焦意味着它将无法使用键盘进行导航。 – dlannoye 2009-08-13 22:55:59

1

经过与WPF小组的讨论后,我发现这只是WPF的一个问题。

对于我的情况,我试图创建一个用于每个TreeViewItem的拖放对话框。我玩弄了不同的控件,试图获得我需要的样子,并且发现ComboBox的Popup部分在TreeView中工作正常。

因此,我结束了在TreeView中使用ComboBox并强制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> 
0

嗯,我在那里有一个TreeView显示了使用数据模板和多用户控制和用户控制的一个阶层项目是在它弹出一个切换按钮同样的问题。

这会完全冻结,根本不会回应。此问题与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>