Подтвердить что ты не робот

TemplateBinding для DependencyProperty на настраиваемом элементе управления не работает

В настоящее время я работаю над простой пользовательской кнопкой, которая использует предоставленные пользователем изображения в качестве фона для нажатых и нормальных состояний. У меня много кнопок, поэтому я решил написать пользовательскую кнопку и реализовать два свойства для изображений нажатых и нормальных состояний.

Вот код, который я использую

public partial class ThemeableButton : Button
{
    public ThemeableButton()
    {
        InitializeComponent();
    }


    public static readonly DependencyProperty PressedContentBackgroundSourceProperty = DependencyProperty.Register(
                    "PressedContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null);
    public ImageSource PressedContentBackgroundSource
    {
        get { return (ImageSource)GetValue(PressedContentBackgroundSourceProperty); }
        set
        {
            (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation; 
            SetValue(PressedContentBackgroundSourceProperty, value);
        }
    }


    public static readonly DependencyProperty NormalContentBackgroundSourceProperty =
        DependencyProperty.Register("NormalContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null);

    public ImageSource NormalContentBackgroundSource
    {
        get { return (ImageSource)GetValue(NormalContentBackgroundSourceProperty); }
        set
        {
            (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation;
            SetValue(NormalContentBackgroundSourceProperty, value);
        }
    }
}

Я написал стиль для этой кнопки следующим образом

        <Style x:Key="ThemeableButtonTemplate" TargetType="MJbox_UIComponents_Controls:ThemeableButton">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="MJbox_UIComponents_Controls:ThemeableButton">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding NormalContentBackgroundSource}">
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding PressedContentBackgroundSource}">
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0">
                            <Image x:Name="ButtonBackground" Stretch="None" Source="{TemplateBinding NormalContentBackgroundSource}"/>
                        </Border>       
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Я попробовал простой пример

<Controls:ThemeableButton Style="{StaticResource ThemeableButtonTemplate}" x:Name="btnDidntNeedIt" NormalContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonUnselected}"
                                   PressedContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonSelected}"
         />

но изображение не отображается, я попытался удалить TemplateBinding из стиля и заменил его относительным источником на файл изображения, и он работал нормально. Я просто не хочу создавать индивидуальный стиль для каждой кнопки в приложении. Любое возможное обходное решение?

4b9b3361

Ответ 1

Я столкнулся с этим раньше, TemplateBinding не работает для пользовательских свойств зависимостей на элементах управления. См. Следующие вопросы:

проблемы с привязкой шаблона и привязкой настраиваемого компонента

TemplateBinding не работает в некоторых случаях (при использовании TranslateTransform)

Я всегда использовал это:

{Binding MyProperty, RelativeSource={RelativeSource TemplatedParent}}

Это семантически то же самое, что и TemplateBinding, а также поддерживает конвертеры значений и т.д.