2015-06-19 64 views
1

我找到解決方案Setter.TargetName does not work against an element from the BasedOn setting。 但我不明白他是如何向我推銷他的。 我有一個類:更改複選框中的默認位圖

public class MyCheckBox: CheckBox 
{ 
    public bool DefaultValue 
    { 
    get { return (bool)GetValue(DefaultValueProperty); } 
    set { SetValue(DefaultValueProperty, value); } 
    } 
    public static readonly DependencyProperty DefaultValueProperty = 
     DependencyProperty.Register("DefaultValue", typeof(bool), typeof(MyCheckBox), new UIPropertyMetadata(false)); 


    protected override void OnToggle() 
    { 
    this.IsChecked = this.IsChecked == null ? !DefaultValue : this.IsChecked.Value ? false : true; 
    } 
} 

和XAML

<Style TargetType="{x:Type CheckBox}"> 
    <Style.Resources> 
    <Imaging:BitmapImage x:Key="CheckBoxStatusSource" UriSource="FalseIfNull.png"/> <!-- icon if [IsChecked] is [null] --> 
    </Style.Resources> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type CheckBox}"> 
     <Image x:Name="CheckBoxStatus" Source="{DynamicResource CheckBoxStatusSource}"/> 
     <ControlTemplate.Triggers> 
      <Trigger Property="IsChecked" Value="True"> 
      <Setter TargetName="CheckBoxStatus" Property="Source" Value="b.png"/><!-- icon if [IsChecked] is [true] --> 
      </Trigger> 
      <Trigger Property="IsChecked" Value="False"> 
      <Setter TargetName="CheckBoxStatus" Property="Source" Value="c.png"/><!-- icon if [IsChecked] is [false] --> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<Style TargetType="{x:Type My:MyCheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}"> 
    <Style.Triggers> 
    <Trigger Property="DefaultValue" Value="true"> 
     <!-- !!!!!!!!!!!!!!This need change [UriSource] in [CheckBoxStatusSource] to "TrueIfNull.png"!!!!!!!!!!!!!! --> 
    </Trigger> 
    </Style.Triggers> 
</Style> 

也許還有另一種解決方案

回答

1

除非你需要延長CheckBox其他原因,你想在這裏做什麼可以也可以使用附加屬性來完成,並且它可以讓您爲所有CheckBox擁有一個單獨的Style

public static class CheckBoxExtensions 
{ 
    public static void SetDefaultValue(CheckBox element, bool value) 
    { 
     element.SetValue(DefaultValueProperty, value); 
    } 
    public static bool GetDefaultValue(CheckBox element) 
    { 
     return (bool)element.GetValue(DefaultValueProperty); 
    } 
    // Using a DependencyProperty as the backing store for DefaultValue. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty DefaultValueProperty = 
     DependencyProperty.RegisterAttached("DefaultValue", typeof(bool), typeof(CheckBoxExtensions), new UIPropertyMetadata(false)); 
} 

此屬性現在可供您在任何CheckBox在解決方案中使用,並在任何方式與您使用您的CheckBox模板。在這種情況下...

<Style TargetType="{x:Type CheckBox}"> 
    <Style.Resources> 
    <Imaging:BitmapImage x:Key="CheckBoxStatusSourceFalse" UriSource="FalseIfNull.png"/> <!-- icon if [IsChecked] is [null] and [DefaultValue] is [false] --> 
    <Imaging:BitmapImage x:Key="CheckBoxStatusSourceTrue" UriSource="TrueIfNull.png"/> <!-- icon if [IsChecked] is [null] and [DefaultValue] is [true] --> 
    </Style.Resources> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type CheckBox}"> 
     <Image x:Name="CheckBoxStatus" Source="{DynamicResource CheckBoxStatusSourceFalse}"/> 
     <ControlTemplate.Triggers> 
      <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition Property="local:CheckBoxExtensions.DefaultValue" Value="True" /> 
       <Condition Property="IsChecked" Value="{x:Null}" /> 
      </MultiTrigger.Conditions> 
      <Setter TargetName="CheckBoxStatus" Property="Source" Value="{DynamicResource CheckBoxStatusSourceFalse}"/> 
      </MultiTrigger> 
      <Trigger Property="IsChecked" Value="True"> 
      <Setter TargetName="CheckBoxStatus" Property="Source" Value="b.png"/><!-- icon if [IsChecked] is [true] --> 
      </Trigger> 
      <Trigger Property="IsChecked" Value="False"> 
      <Setter TargetName="CheckBoxStatus" Property="Source" Value="c.png"/><!-- icon if [IsChecked] is [false] --> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

編輯:即使你仍然需要擴展CheckBox,這種風格會工作爲經常CheckBox和你MyCheckBox實現。只需創建另一個基於這個風格。

<Style TargetType="{x:Type My:MyCheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}"> 
    ... 
</Style> 

如果你要訪問的代碼隱藏DefaultValue屬性,你可以這樣來做:

CheckBoxExtensions.SetDefaultValue(checkBox, true); 
bool defaultValue = CheckBoxExtensions.GetDefaultValue(checkBox); 
+0

但我失去了'保護覆蓋無效OnToggle()':( –

+1

可以保持你的'MyCheckBox',這個樣式也適用於他們,你可以在C#代碼中設置'DefaultValue',我將編輯我的答案以反映這一點 – almulo

+0

好主意!我檢查它!UPD:它的工作! –