Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass parameter to a customized template

I've edited a template from a checkbox, then I added an image into it without defining its "Source" property.

Style :

<Style x:Key="ImageCheckbox" TargetType="{x:Type CheckBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
        <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <Image x:Name="image" Width="20" Height="20" Stretch="UniformToFill"/>                      
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasContent" Value="true">
                            <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
                            <Setter Property="Padding" Value="4,0,0,0"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>       

My question is how to pass that "Source" property (in XAML) to "ImageCheckBox" template in this code :

<CheckBox Content="" Margin="0,2,0,0" Name="btTogglePalette" Grid.Row="1" Command="Helpers:UICommands.TogglePalette" 
                              IsChecked="{Binding Path=PaletteStatus, Mode=TwoWay}" VerticalAlignment="Center" HorizontalAlignment="Center" 
                              Style="{DynamicResource ImageCheckbox}">

So that the image will show the passed parameter.

Thank you

like image 786
Arslan Avatar asked Sep 05 '11 14:09

Arslan


3 Answers

You can use the Tag property

<CheckBox Tag="YourImageSource"
          Style="{DynamicResource ImageCheckbox}"/>

And then bind Source of the Image in the Template to Tag

<Image x:Name="image" Width="20" Height="20" Stretch="UniformToFill"
       Source="{Binding RelativeSource={RelativeSource TemplatedParent},
                        Path=Tag}"/>

However, I'd prefer using an Attached Property for a number of reasons.

  • The intention of using Tag isn't really clear
  • You might be using the Tag property for something else
  • You might want to use more than one ImageSource etc.

The usage of an Attached Property is exactly the same except you must put parentheses around the attached property.

<CheckBox local:ImageSourceExtension.ImageSource="YourImageSource"
          Style="{DynamicResource ImageCheckbox}"/>

In Template

<Image x:Name="image" Width="20" Height="20" Stretch="UniformToFill"
       Source="{Binding RelativeSource={RelativeSource TemplatedParent},
                        Path=(local:ImageSourceExtension.ImageSource)}"/>

And here is the attached property ImageSource

public class ImageSourceExtension
{
    public static DependencyProperty ImageSourceProperty =
        DependencyProperty.RegisterAttached("ImageSource",
                                            typeof(ImageSource),
                                            typeof(ImageSourceExtension),
                                            new PropertyMetadata(null));
    public static ImageSource GetImageSource(DependencyObject target)
    {
        return (ImageSource)target.GetValue(ImageSourceProperty);
    }
    public static void SetImageSource(DependencyObject target, ImageSource value)
    {
        target.SetValue(ImageSourceProperty, value);
    }
}
like image 114
Fredrik Hedblad Avatar answered Nov 02 '22 22:11

Fredrik Hedblad


You need to define Source in Image of ImageCheckbox template or create your own CheckBox deriving from standard CheckBox, add dependence property of type ImageSource to custom CheckBox, define custom template with binding to Source property of newly created control.

like image 1
Kirill Polishchuk Avatar answered Nov 02 '22 22:11

Kirill Polishchuk


There is no way to pass custom parameters to a style or template. You can only access properties on the control or bound data. That said, you may be able to abuse the checkbox's Tag property to accomplish this but I'm not 100% it will work.

The proper way to do it is to create a new custom control that derives from Checkbox and add a dependency property holding your image (of type ImageSource). That way, from your control template inside generic.xaml you can do

<!-- in generic.xaml, inside the ControlTemplate for your ImageCheckbox style -->
<Image Source="{TemplateBinding ImageSource}" />

and where you instantiate your checkbox you do

<local:ImageCheckbox ImageSource="Resources/MyImage.png" ...etc... />
like image 9
Isak Savo Avatar answered Nov 02 '22 23:11

Isak Savo