2009-09-03 9 views

Respuesta

19

Es posible, pero necesitaría reimprimirlo para lograr la perfección. Se puede obtener la mayor parte del camino reemplazando un parámetro del sistema de la siguiente manera:

<ComboBox xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
    <ComboBox.Resources> 
     <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">0</sys:Double> 
    </ComboBox.Resources> 
    <ComboBoxItem>One</ComboBoxItem> 
    <ComboBoxItem>Two</ComboBoxItem> 
    <ComboBoxItem>Three</ComboBoxItem> 
</ComboBox> 

Sin embargo, no es perfecta, porque el rectángulo de selección todavía asume que hay un botón desplegable presente.

+4

Tuve que agregar xmlns: sys = "clr-namespace: System; assembly = mscorlib", para que funcione :) – codymanix

+0

¿Crees que es posible usar esto junto con la vinculación de datos? –

14

Todos los controles WPF son "impersonales", por lo que puede redefinir por completo su apariencia. Sin embargo, no es simple y aún menos para ComboBox. ComboBox usa una de dos plantillas, dependiendo de si es editable. La versión no editable utiliza el ToggleButton para la apariencia del control, por lo que puede eliminar el dibujo de la flecha (consulte a continuación). La versión editable usa un TextBox y un ToggleButton, y si no tiene ToggleButton, no se abre. Así que aquí hay una plantilla sin ToggleButton; Depende de usted agregar el código para manejar los clics en la plantilla editable. (O si no necesita editar, puede forzar que IsEditable sea falso y terminar con él)

Advertencia: esta es la plantilla Aero y utiliza Aero Chrome, por lo que no se mostrará en otros temas . Para que eso suceda, deberá extraer las plantillas para cada tema y hacer los cambios apropiados o eliminar el tema cromado y dibujar sus propios bordes.

Añadir esta definición de espacio de nombres y añadir una referencia a PresentationFramework.Aero:

xmlns:t="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 

A continuación, añada lo siguiente a su ventana/Recursos de control:

<Style x:Key="ComboBoxFocusVisual"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="4,4,21,4" SnapsToDevicePixels="true"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0"> 
     <GradientStop Color="#F3F3F3" Offset="0"/> 
     <GradientStop Color="#EBEBEB" Offset="0.5"/> 
     <GradientStop Color="#DDDDDD" Offset="0.5"/> 
     <GradientStop Color="#CDCDCD" Offset="1"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/> 
    <Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry> 
    <Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}"> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="IsTabStop" Value="false"/> 
     <Setter Property="Focusable" Value="false"/> 
     <Setter Property="ClickMode" Value="Press"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ToggleButton}"> 
        <t:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"> 
         <!-- Remove ToggleButton appearance; we still need the ToggleButton because it displays the content. 
         <Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> 
          <Path x:Name="Arrow" Fill="Black" HorizontalAlignment="Center" Margin="3,1,0,0" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/> 
         </Grid> 
         --> 
        </t:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsChecked" Value="true"> 
          <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/> 
         </Trigger> 
         <!-- Remove ToggleButton appearance trigger 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/> 
         </Trigger> 
         --> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute"> 
     <GradientStop Color="#ABADB3" Offset="0.05"/> 
     <GradientStop Color="#E2E3EA" Offset="0.07"/> 
     <GradientStop Color="#E3E9EF" Offset="1"/> 
    </LinearGradientBrush> 
    <Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}"> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="AllowDrop" Value="true"/> 
     <Setter Property="MinWidth" Value="0"/> 
     <Setter Property="MinHeight" Value="0"/> 
     <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TextBox}"> 
        <ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}"> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="IsTabStop" Value="false"/> 
     <Setter Property="Focusable" Value="false"/> 
     <Setter Property="ClickMode" Value="Press"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ToggleButton}"> 
        <t:ButtonChrome x:Name="Chrome" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RoundCorners="false"> 
         <Path x:Name="Arrow" Fill="Black" HorizontalAlignment="Center" Margin="0,1,0,0" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/> 
        </t:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsChecked" Value="true"> 
          <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}"> 
     <Grid x:Name="Placement" SnapsToDevicePixels="true"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="Auto"/> 
      </Grid.ColumnDefinitions> 
      <Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Grid.ColumnSpan="2"> 
       <t:SystemDropShadowChrome x:Name="Shdw" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=Placement}" Color="Transparent"> 
        <Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1"> 
         <ScrollViewer> 
          <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/> 
         </ScrollViewer> 
        </Border> 
       </t:SystemDropShadowChrome> 
      </Popup> 
      <t:ListBoxChrome x:Name="Border" Grid.ColumnSpan="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}"/> 
      <TextBox x:Name="PART_EditableTextBox" Margin="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"/> 
      <!-- Remove the ToggleButton button; now you make the textbox clickable.... 
       <ToggleButton Style="{StaticResource ComboBoxToggleButton}" Grid.Column="1" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/> 
      --> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="IsKeyboardFocusWithin" Value="true"> 
       <Setter Property="Foreground" Value="Black"/> 
      </Trigger> 
      <Trigger Property="IsDropDownOpen" Value="true"> 
       <Setter Property="RenderFocused" TargetName="Border" Value="true"/> 
      </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> 
      <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> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 
    <Style x:Key="ButtonlessComboBoxStyle" 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="*"/> 
          <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/> 
         </Grid.ColumnDefinitions> 
         <Popup x:Name="PART_Popup" Margin="1" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Grid.ColumnSpan="2"> 
          <t: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="1"> 
            <ScrollViewer CanContentScroll="true"> 
             <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/> 
            </ScrollViewer> 
           </Border> 
          </t:SystemDropShadowChrome> 
         </Popup> 
         <ToggleButton Style="{StaticResource ComboBoxReadonlyToggleButton}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/> 
         <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" IsHitTestVisible="false" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/> 
        </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"/> 
       <Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 

A continuación, utilice:

<ComboBox HorizontalAlignment="Left" Width="120" Style="{DynamicResource ButtonlessComboBoxStyle}"> 
    <ComboBox.Items> 
     <ComboBoxItem>One</ComboBoxItem> 
     <ComboBoxItem>Two</ComboBoxItem> 
     <ComboBoxItem>Three</ComboBoxItem> 
    </ComboBox.Items> 
</ComboBox> 

<ComboBox HorizontalAlignment="Left" Width="120" IsEditable="True" Style="{DynamicResource ButtonlessComboBoxStyle}"> 
    <ComboBox.Items> 
     <ComboBoxItem>One</ComboBoxItem> 
     <ComboBoxItem>Two</ComboBoxItem> 
     <ComboBoxItem>Three</ComboBoxItem> 
    </ComboBox.Items> 
</ComboBox> 

Nota: Los estilos están referenciados como DynamicResource porque se basan en el tema Chrome, por lo que deben responder a los cambios en el estilo visual del sistema operativo. Si quita el cromo y usa los bordes de WPF, debe hacer referencia a estos como StaticResource para el rendimiento.

+1

Gracias por su código y buenas explicaciones. Lástima que solo funciona en aero :( – codymanix

+0

Siempre puede hacer referencia a un tema de MS diferente, como Luna, en lugar de usar Aero. Utilizamos Luna en nuestros temas, ya que nuestras PC de oficina ejecutan XP. – TabbyCool

Cuestiones relacionadas