1

I find solution Setter.TargetName does not work against an element from the BasedOn setting. But I do not understand how prement him to me. I have a class:

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

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

Perhaps there is another solution

Community
  • 1
  • 1

1 Answers1

1

Unless you need to extend CheckBox for other reasons, what you're trying to do here can be done with Attached Properties too, and it would allow you to have one single Style for all your CheckBoxes.

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));
}

This property is now available for you to use in any CheckBox in your solution, and in any Style and Template you use for your CheckBoxes. In this case...

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

EDIT: Even if you still need to extend CheckBox, this Style would work for both regular CheckBox and your MyCheckBox implementation. Just create another Style that's based on this one.

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

And if you want to access the DefaultValue property from code-behind, you can do it this way:

CheckBoxExtensions.SetDefaultValue(checkBox, true);
bool defaultValue = CheckBoxExtensions.GetDefaultValue(checkBox);
almulo
  • 4,918
  • 1
  • 20
  • 29