使用数据触发器更改WPF Combobox箭头

时间:2016-10-24 18:37:30

标签: wpf combobox

我正在使用我在CodeProject [http://www.codeproject.com/Articles/563862/Multi-Select-ComboBox-in-WPF]上找到的多选组合框。

我正在尝试根据是否选择了所有项目来更改箭头的形状。但是我无法在setter中正确引用x:箭头名称。

以下是我一直在尝试修改的代码:

<UserControl x:Class="Z_Sys_UI.System.MultiSelectComboBox"
         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" >
<ComboBox
    x:Name="MultiSelectCombo"  
    SnapsToDevicePixels="True"
    OverridesDefaultStyle="True"
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    ScrollViewer.CanContentScroll="True"
    IsSynchronizedWithCurrentItem="True"
                       >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Title}"
                      IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
                      Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
                       Click="CheckBox_Click"           />
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.Template>
        <ControlTemplate TargetType="ComboBox">
            <Grid >
                <ToggleButton 
                    x:Name="ToggleButton" 
                   Grid.Column="2" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                    Focusable="false"                           
                    ClickMode="Press" HorizontalContentAlignment="Left" >
                    <ToggleButton.Template>
                        <ControlTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="18"/>
                                </Grid.ColumnDefinitions>
                                <Border
              x:Name="Border" 
              Grid.ColumnSpan="2"
              CornerRadius="2"
              Background="White"
              BorderBrush="Black"
              BorderThickness="1,1,1,1" />
                                <Border 
                x:Name="BorderComp" 
              Grid.Column="0"
              CornerRadius="2" 
              Margin="1" 
             Background="White"
              BorderBrush="Black"
              BorderThickness="0,0,0,0" >
                                    <TextBlock Text="{Binding Path=Text,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" 
                                           Background="White" Padding="3" />
                                </Border>
              <Path 
              x:Name="Arrow"
              Grid.Column="1"     
              Fill="Black"
              HorizontalAlignment="Center"
              VerticalAlignment="Center"
              Data="M 0 0 L 4 4 L 8 0 Z">
                                </Path>
                            </Grid>
                        </ControlTemplate>
                    </ToggleButton.Template>
                </ToggleButton>
                <Popup 
                    Name="Popup"
                    Placement="Bottom"                        
                    AllowsTransparency="True" 
                    Focusable="False"  IsOpen="{TemplateBinding IsDropDownOpen}"
                    PopupAnimation="Slide">
                    <Grid 
                              Name="DropDown"
                              SnapsToDevicePixels="True"  
                        MinWidth="{TemplateBinding ActualWidth}"
                              MaxHeight="{TemplateBinding MaxDropDownHeight}">
                        <Border 
                                x:Name="DropDownBorder" 
                               BorderThickness="1" Background="White"
                                BorderBrush="Black"/>
                        <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True" DataContext="{Binding}">
                            <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 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>
                <DataTrigger Binding="{Binding Path=SelectAll, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" Value="false" >
                    <Setter TargetName="Arrow" Property="Data" Value="M 0 0 L 2 2 L 8 0 Z" />
                </DataTrigger>
            </ControlTemplate.Triggers>

        </ControlTemplate>
    </ComboBox.Template>
</ComboBox>

现在它给出了错误,表示无法识别名称箭头,并且无法识别或无法访问成员数据。

我尝试触发的SelectAll路径也可能无法正常工作。 CodeProject代码似乎没有完全实现该属性。我稍后会处理这种可能性。

提前感谢您的任何答案或建议。

1 个答案:

答案 0 :(得分:2)

名称Arrow超出了ComboBox ControlTemplate的范围,因为它在ToggleButton ControlTemplate中定义。解决方案变得简单:只需将触发器放在目标控件所在范围内的模板中。

<ToggleButton.Template>
    <ControlTemplate>
        <Grid>

            <!-- snip snip snip -->
            <!-- snip snip snip -->
            <!-- snip snip snip -->

            <Path 
                x:Name="Arrow"
                Grid.Column="1"     
                Fill="Black"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Data="M 0 0 L 4 4 L 8 0 Z"
                >
            </Path>
        </Grid>
        <ControlTemplate.Triggers>
            <DataTrigger 
                Binding="{Binding Path=SelectAll, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" 
                Value="false" >
                <Setter 
                    TargetName="Arrow" 
                    Property="Data" 
                    Value="M 0 0 L 2 2 L 8 0 Z"  
                    />
            </DataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</ToggleButton.Template>

我假设SelectAll是一个布尔依赖属性,并且是MultiSelectComboBox的成员,因为这似乎是你用它做的事情所暗示的。这是我的依赖属性定义:

    public static readonly DependencyProperty SelectAllProperty =
        DependencyProperty.Register("SelectAll", typeof(bool), typeof(MultiSelectComboBox),
            new PropertyMetadata(false));

以下是我使用的XAML测试:

<StackPanel
    Orientation="Vertical"
    >
    <CheckBox Content="SelectAll" x:Name="SelectAllCheckBox" />
    <local:MultiSelectComboBox 
        SelectAll="{Binding IsChecked, ElementName=SelectAllCheckBox}" />
</StackPanel>