2016-10-24 3 views
0

Ich verwende eine Mehrfachauswahl-Combobox, die ich in CodeProject [http://www.codeproject.com/Articles/563862/Multi-Select-ComboBox-in-WPF]] gefunden habe.WPF-Combobox-Pfeil mit einem Datentrigger ändern

Ich versuche die Form des Pfeils zu ändern, je nachdem, ob alle Elemente ausgewählt sind oder nicht. Allerdings konnte ich den X: Name des Arrow im Setter nicht korrekt referenzieren.

Hier ist der Code, ich habe zu ändern versucht:

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

Gerade jetzt ist es Fehler, dass der Name Pfeil wird nicht erkannt, und die Mitgliederdaten nicht erkannt sagen geben wird oder ist nicht zugänglich.

Es ist auch möglich, dass der SelectAll-Pfad, von dem ich versuche auszulösen, nicht funktioniert. Der CodeProject-Code scheint diese Eigenschaft nicht vollständig implementiert zu haben. Ich werde mich später mit dieser Möglichkeit befassen.

Vielen Dank im Voraus für alle Antworten oder Vorschläge.

+0

Ein Trigger, die Steuerelemente ändert, die es gibt innerhalb der ToggleButton Vorlage in der ToggleButton Vorlage selbst sein muss. Aber wie bindet es dann an Eigenschaften der ComboBox? Wenn Sie keine AncestorType-Bindung für die Arbeit an einem DataTrigger in der ControlTemplate des ToggleButtons erhalten, würde ich versuchen, den Trigger, den Sie haben, zu übernehmen und die gesamte Vorlage des ToggleButton zu ändern. Erstellen Sie einfach zwei Kopien der ToggleButton ControlTemplate, eine mit jeder Version des Pfeils. –

Antwort

2

Der Name Arrow ist außerhalb des Gültigkeitsbereiches in den ComboBoxControlTemplate, weil es in den ToggleButtonControlTemplate definiert ist. Die Lösung stellt sich als einfach heraus: Einfach den Trigger in die Vorlage setzen, in der sich das Zielsteuerelement befindet.

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

Ich gehe davon aus, dass SelectAll ist eine boolean Abhängigkeitseigenschaft, und ein Mitglied der MultiSelectComboBox, denn das durch impliziert zu werden scheint, was man damit tun. Hier ist meine Abhängigkeitseigenschaft Definition:

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

Und hier ist der Test XAML ich verwendet:

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

So weit so gut, danke. Das Setzen des Triggers in die Vorlage, in der das Ziel-Steuerelement im Umfang ist, behob die xaml-Fehler, die ich bekam. 'SelectAll' ist eine boolesche Abhängigkeitseigenschaft und ich werde sehen, ob das im nächsten Schritt funktioniert. – dev1998

+0

Es ist alles gut. Ich habe Ihre XAML-Änderung implementiert und es hat beim ersten Mal funktioniert. Ich hatte bereits einige Änderungen am bestehenden Code vorgenommen, um sicherzustellen, dass SelectAll richtig eingestellt wurde. – dev1998

+0

@ dev1998 Gute Nachrichten! –

Verwandte Themen