2014-09-24 3 views
1

Есть ли простой и простой способ реализовать кнопку выбора цвета, подобную той, что находится в MS Word?WPF: простая кнопка выбора цвета в MSWord

Я хочу, чтобы пользователь выбирал из числа предопределенных цветов в выпадающем списке. Выбранный цвет должен отображаться, когда кнопка закрыта. Когда пользователь нажимает кнопку, должно запускаться событие или команда. Я хочу использовать один экземпляр кнопки, чтобы установить цвет текста в RichTextBox, а другой - установить цвет фона (аналогично MS Word).

Мой первый подход состоял в использовании ComboBox с DataTemplate, который содержит кнопку. Это не работает: команда кнопки не запускается, когда пользователь нажимает на нее. Вместо этого открывается раскрывающееся меню ComboBox. Я не знаю точную причину, но, возможно, атрибуты IsHitTestVisible = false в шаблоне по умолчанию для ComboBox? См: http://msdn.microsoft.com/en-us/library/dd334408%28v=vs.95%29.aspx

<UserControl x:Class="MyBrushPicker" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d"    
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    Height="Auto" Width="Auto" MinWidth="50"> 
    <UserControl.Resources> 

     <!-- 
     Provide two different DataTemplates: 
     - SelectionBoxTemplate is used to display the selected color when the ComboBox is closed. 
      It contains a button which should be clickable (does not work). 
     - NormalItemTemplate is used to display a color in the opened ComboBox popup. 
     See: 
     http://stackoverflow.com/questions/2214696/wpf-how-to-customize-selectionboxitem-in-combobox 
     --> 

     <DataTemplate x:Key="NormalItemTemplate"> 
      <Border Height="44" Width="44" Margin="3,3,3,3" BorderThickness="1" BorderBrush="Black" Background="{Binding Mode=OneWay}"/> 
     </DataTemplate> 

     <DataTemplate x:Key="SelectionBoxTemplate"> 
      <!-- This button cannot be clicked: PreviewMouseDown and Button_Click events are never triggered. --> 
      <Button Click="Button_Click" PreviewMouseDown="Button_PreviewMouseDown"> 
       <Border Height="44" Width="44" Margin="3,3,3,3" BorderThickness="1" BorderBrush="Black" Background="{Binding Mode=OneWay}"/> 
      </Button> 
     </DataTemplate> 

     <DataTemplate x:Key="CombinedTemplate"> 

      <ContentPresenter x:Name="Presenter" 
        Content="{Binding}"         
        ContentTemplate="{StaticResource NormalItemTemplate}" /> 

      <DataTemplate.Triggers> 
       <DataTrigger 
        Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}" 
        Value="{x:Null}"> 

        <Setter TargetName="Presenter" Property="ContentTemplate" 
         Value="{StaticResource SelectionBoxTemplate}" /> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </DataTemplate> 
    </UserControl.Resources> 

    <ComboBox IsReadOnly="True" IsEditable="False" 
       ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=SelectableBrushes, Mode=OneWay}" 
       SelectedItem="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=SelectedBrush, Mode=TwoWay}" 
       ScrollViewer.VerticalScrollBarVisibility="Auto" 
       MinHeight="50" 
       MaxDropDownHeight="200" 
       ItemTemplate="{StaticResource CombinedTemplate}" 
       > 

     <ComboBox.Resources> 
      <Style TargetType="ComboBox"> 
       <Setter Property="ItemsPanel"> 
        <Setter.Value> 
         <ItemsPanelTemplate> 
          <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="200" /> 
         </ItemsPanelTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
      <Style TargetType="ComboBoxItem"> 
       <Setter Property="Width" Value="50" /> 
       <Setter Property="Height" Value="50" /> 
      </Style> 
     </ComboBox.Resources> 

    </ComboBox> 
</UserControl> 

Есть ли способ, чтобы правильно сделать кнопку работы? Есть ли какие-нибудь лучшие подходы?

EDIT: Использование инструмента Snoop показало, что атрибут IsHitTestVisible неназванного ContentPresenter внутри ComboBox фактически установлен в false (ValueSource: ParentTemplate). Если я установил это свойство в true, используя Snoop, кнопка станет интерактивной.

Могу ли я изменить это свойство из стиля? По крайней мере, следующее не работает:

<ComboBox.Resources> 
    <Style TargetType="ContentPresenter"> 
     <Setter Property="IsHitTestVisible" Value="True" /> 
    </Style> 
</ComboBox.Resources> 

ответ

2

Предполагая, что вы не просто делаете это в качестве учебного упражнения (которые делают с использованием библиотеки бессмысленно) ...

Взгляните на: Extended WPF Toolkit - Color Picker

Я использовал его раньше для простого цветового набора WPF для плагина и воспроизведения, и он должен хорошо решить вашу проблему.

+1

Существует даже SplitItemsButton - см .: https://dropdownbuttonlib.codeplex.com/ Но мне нужно избегать сторонних библиотек. – devar

Смежные вопросы