更改可编辑ComboBox的行为

时间:2009-07-01 14:17:01

标签: c# .net wpf xaml

我想更改可编辑ComboBox的行为。这是我想要的行为:

当ComboBox打开时,当IsEditable为true时,使TextBox(PART_EditableTextBox)可见。我在ControlTemplate.Triggers部分中已经解决了这个问题:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsEditable" Value="True" />
        <Condition Property="IsDropDownOpen" Value="True" />
    </MultiTrigger.Conditions>
    <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
</MultiTrigger>

问题在于隐藏PART_EditableTextBox时,不会显示内容。因此,在选择项目后,ComboBox保持空白。只有当IsEditable = true时才会这样。

以下是完整的ComboBox模板代码。

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Animations.xaml"/>
    <ResourceDictionary Source="Brushes.xaml"/>

</ResourceDictionary.MergedDictionaries>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<ControlTemplate x:Key="EditableComboBoxToggleButton" TargetType="ToggleButton">
    <ControlTemplate.Resources>

    </ControlTemplate.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>

        <!-- The drop down button on the right -->
        <Border Grid.ColumnSpan="2" BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
            <Border x:Name="Border" Background="{StaticResource ButtonBaseBrush}" BorderBrush="{StaticResource ButtonInnerBorderBrush}" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="0.507*"/>
                        <RowDefinition Height="0.493*"/>
                    </Grid.RowDefinitions>
                    <Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4" Background="{StaticResource ButtonLitBrush}" />
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/>
                    <Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0" Background="{StaticResource ButtonGlowOverlay}" />
                </Grid>
            </Border>
        </Border>

        <!-- The white area where the selected item is displayed (also part of the button) -->
        <Border 
  Grid.Column="0"
  CornerRadius="2,0,0,2" 
  Margin="1" 
  Background="{StaticResource WindowBackgroundBrush}" 
  BorderBrush="Black"
  BorderThickness="1" />

        <!-- The down-arrow -->
        <Path 
  x:Name="Arrow"
  Grid.Column="1"     
  Fill="White"
  HorizontalAlignment="Center"
  VerticalAlignment="Center"
  Data="M 0 0 L 4 4 L 8 0 Z"/>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter Property="Opacity" TargetName="shine" Value="0.4"/>
            <Setter Property="Background" TargetName="Border" Value="#DCE38819"/>
            <Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
        </Trigger>
        <Trigger Property="ToggleButton.IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
    <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>

<Style x:Key="EditableGlassComboBox" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="MinWidth" Value="120"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="Height" Value="34" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton 
        Name="ToggleButton" 
        Template="{StaticResource EditableComboBoxToggleButton}"
        IsEnabled="{TemplateBinding IsEnabled}"
        Grid.Column="2" 
        Focusable="false"
        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
        ClickMode="Press">
                    </ToggleButton>

                    <ContentPresenter
        Name="ContentSite"
        IsHitTestVisible="False" 
        Content="{TemplateBinding SelectionBoxItem}"
        ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
        ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
        Margin="3,3,23,3"
        VerticalAlignment="Center"
        HorizontalAlignment="Stretch" />

                    <TextBox x:Name="PART_EditableTextBox"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        Background="Red"
        Grid.Column="0"
        Style="{x:Null}" 
        Template="{StaticResource ComboBoxTextBox}" 
        FontSize="16"
        Margin="5,5,23,5"
        Focusable="True" 
        Visibility="Collapsed"
        IsReadOnly="{TemplateBinding IsReadOnly}"/>

                    <Popup 
        Name="Popup"
        Placement="Bottom"
        IsOpen="{TemplateBinding IsDropDownOpen}"
        AllowsTransparency="True" 
        Focusable="False"
        PopupAnimation="Slide">

                        <Grid 
          Name="DropDown"
          SnapsToDevicePixels="True"                
          MinWidth="{TemplateBinding ActualWidth}"
          MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border 
            x:Name="DropDownBorder"
            Background="{StaticResource WindowBackgroundBrush}"
            BorderThickness="1"
            BorderBrush="{StaticResource ComboItemsBorderBrush}"/>
                            <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsEditable" Value="True" />
                            <Condition Property="IsDropDownOpen" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
    </Style.Triggers>
</Style>

2 个答案:

答案 0 :(得分:1)

我通过完全忽略ComboBox并创建我自己的UserControl来解决我的问题,该UserControl具有TextBox和带有ListBox的Popup。在后面的代码中,我添加了过滤并在正确的时间弹出/关闭弹出窗口。

答案 1 :(得分:0)

您必须在TextBox后面放置一个TextBlock或ContentPresenter(绑定到相同的值),这样当您隐藏TextBox时,TextBlock变为可见并显示所选的值。

实现这一目标的最简单方法是将它们放在同一个网格中:

<Grid>
<ContentPresenter Content="{TemplateBinding Text}"/>
<TextBox x:Name="PART_EditableTextBox"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        Background="Red"
        Grid.Column="0"
        Style="{x:Null}" 
        Template="{StaticResource ComboBoxTextBox}" 
        FontSize="16"
        Margin="5,5,23,5"
        Focusable="True" 
        Visibility="Collapsed"
        IsReadOnly="{TemplateBinding IsReadOnly}"/>
</Grid>