【问题标题】:Change behaviour of editable ComboBox更改可编辑组合框的行为
【发布时间】:2009-07-01 14:17:01
【问题描述】:

我想更改可编辑组合框的行为。这是我想要的行为:

使文本框 (PART_EditableTextBox) 仅在 IsEditable 为真时可见在 ComboBox 打开时。我已经在 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>

【问题讨论】:

    标签: c# .net wpf xaml


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您必须在 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>
      

      【讨论】:

      • 谢谢,但这正是我在我发布的代码中所做的!我希望底层的 ContentPresenter 变得可见,但这不会发生!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      • 2018-12-27
      • 2017-07-14
      • 2011-04-14
      • 2012-04-26
      • 2014-07-21
      相关资源
      最近更新 更多