tags:

views:

476

answers:

2

Hi all,

I want to change the behaviour of the editable ComboBox. This is the behaviour I want:

Make the TextBox (PART_EditableTextBox) only visible when IsEditable is true and when the ComboBox is open. I've worked this out in the ControlTemplate.Triggers part:

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

The problem is that when the PART_EditableTextBox is hidden, the content is not shown. So the ComboBox stays blank after I've selected an item. This is only true when IsEditable = true.

Below is the complete ComboBox template code.

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

A: 

You have to put a TextBlock or a ContentPresenter behind the TextBox (bound to the same value) so when you hide the TextBox the TextBlock becomes visible and shows the selected value.

The easiest way to accomplish this is to but them in the same Grid:

<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>
Nir
Thanks, but this is exactly I do in the code I've posted! I would expect the underlying ContentPresenter to become visible, but this does not happen!
Robbert Dam
+1  A: 

I've solved my problem by completely ignoring the ComboBox and creating my own UserControl that has a TextBox and a Popup with a ListBox. In code behind I've added filtering and popup up / closing the popup at the right time.

Robbert Dam