将参数传递给自定义模板

时间:2011-09-05 14:44:56

标签: c# wpf templates xaml

我已经从复选框中编辑了一个模板,然后我在其中添加了一个图像而没有定义它的“Source”属性。

风格:

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

我的问题是如何在此代码中将“Source”属性(在XAML中)传递给“ImageCheckBox”模板:

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

这样图像就会显示传递的参数。

谢谢

3 个答案:

答案 0 :(得分:23)

您可以使用Tag属性

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

然后将ImageTemplate的来源绑定到Tag

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

但是,出于多种原因,我更倾向于使用附属财产。

  • 使用Tag的意图并不是很清楚
  • 您可能正在使用Tag属性进行其他操作
  • 您可能希望使用多个ImageSource等。

附加财产的使用情况完全相同,除非您必须在附加财产周围加上括号。

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

在模板中

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

这是附加属性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);
    }
}

答案 1 :(得分:8)

无法将自定义参数传递给样式或模板。您只能访问控件或绑定数据的属性。也就是说,您可以滥用复选框的Tag属性来完成此操作,但我不是100%它会起作用。

执行此操作的正确方法是创建一个派生自Checkbox的新自定义控件,并添加一个包含图像的依赖项属性(类型为ImageSource)。这样,您可以从generic.xaml中的控件模板中进行操作

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

您实例化复选框的地方

<local:ImageCheckbox ImageSource="Resources/MyImage.png" ...etc... />

答案 2 :(得分:1)

您需要在ImageCheckbox模板的图像中定义Source或创建自己的CheckBox从标准CheckBox派生,将ImageSource类型的依赖属性添加到自定义CheckBox,定义绑定到新创建控件的Source属性的自定义模板。