TemplateBinding来的DependencyProperty上的自定义控制不工作 [英] TemplateBinding to DependencyProperty on a custom control is not working
问题描述
目前,我正在使用用户提供的图片作为压和正常状态的背景简单的自定义按钮。我有很多的按钮,所以我决定写一个自定义按钮和实施压制和正常状态图片两个属性。
下面是我的代码使用
公共部分类ThemeableButton:按钮
{
公共ThemeableButton()
{
的InitializeComponent();
}
公共静态只读的DependencyProperty PressedContentBackgroundSourceProperty = DependencyProperty.Register(
PressedContentBackgroundSource的typeof(ImageSource的)的typeof(ThemeableButton),NULL);
公众的ImageSource PressedContentBackgroundSource
{
{返回(ImageSource的)的GetValue(PressedContentBackgroundSourceProperty); }
组
{
(价值的BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation;
的SetValue(PressedContentBackgroundSourceProperty,值);
}
}
公共静态只读的DependencyProperty NormalContentBackgroundSourceProperty =
DependencyProperty.Register(NormalContentBackgroundSource的typeof(ImageSource的)的typeof(ThemeableButton)空值);
公众的ImageSource NormalContentBackgroundSource
{
{返回(ImageSource的)的GetValue(NormalContentBackgroundSourceProperty); }
组
{
(价值的BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation;
的SetValue(NormalContentBackgroundSourceProperty,值);
}
}
}
我写的风格为这个按钮如下:
<风格X:键=ThemeableButtonTemplate的TargetType =MJbox_UIComponents_Controls:ThemeableButton>
< setter属性=背景值=透明/>
< setter属性=BorderBrushVALUE ={StaticResource的PhoneForegroundBrush}/>
< setter属性=前景VALUE ={StaticResource的PhoneForegroundBrush}/>
< setter属性=了borderThicknessVALUE ={StaticResource的PhoneBorderThickness}/>
< setter属性=的FontFamilyVALUE ={StaticResource的PhoneFontFamilySemiBold}/>
< setter属性=字号VALUE ={StaticResource的PhoneFontSizeMediumLarge}/>
< setter属性=填充VALUE =0/>
< setter属性=模板>
< Setter.Value>
<的ControlTemplate的TargetType =MJbox_UIComponents_Controls:ThemeableButton>
<网格和GT;
< VisualStateManager.VisualStateGroups>
< VisualStateGroup X:NAME =CommonStates>
<的VisualState X:名称=正常>
<情节提要>
< ObjectAnimationUsingKeyFrames Storyboard.TargetProperty =源Storyboard.TargetName =ButtonBackground>
< DiscreteObjectKeyFrame KeyTime =0值={TemplateBinding NormalContentBackgroundSource}>
< / DiscreteObjectKeyFrame>
< / ObjectAnimationUsingKeyFrames>
< /故事板>
< /&的VisualState GT;
<的VisualState X:NAME =按下>
<情节提要>
< ObjectAnimationUsingKeyFrames Storyboard.TargetProperty =源Storyboard.TargetName =ButtonBackground>
< DiscreteObjectKeyFrame KeyTime =0值={TemplateBinding PressedContentBackgroundSource}>
< / DiscreteObjectKeyFrame>
< / ObjectAnimationUsingKeyFrames>
< /故事板>
< /&的VisualState GT;
< / VisualStateGroup>
< /VisualStateManager.VisualStateGroups>
< BORDER了borderThickness ={TemplateBinding了borderThickness}后台={TemplateBinding背景}CornerRadius =0>
<图像X:NAME =ButtonBackground拉伸=无来源={TemplateBinding NormalContentBackgroundSource}/>
< /边框>
< /网格和GT;
< /控件模板>
< /Setter.Value>
< /二传手>
< /样式和GT;
我试过一个简单的例子
<控制:ThemeableButton风格={StaticResource的ThemeableButtonTemplate}X:NAME =btnDidntNeedItNormalContentBackgroundSource ={绑定源= {StaticResource的DefaultTheme},路径= DidntHaveButtonUnselected}
PressedContentBackgroundSource ={绑定源= {StaticResource的DefaultTheme},路径= DidntHaveButtonSelected}
/>
但图像没有显示,我试图从风格去除TemplateBinding和替换它相源的图像文件,它工作得很好。我只是不想创建自定义样式上的应用程序的每个按钮。任何可能的解决方法?
解决方案
我以前也遇到过这种
的 TemplateBinding不会在某些情况下工作(使用TranslateTransform时)
我一直用这个代替:
{结合myProperty的,的RelativeSource = {的RelativeSource TemplatedParent}}
有语义相同TemplateBinding,并且还可以支持值转换器等...
Currently, I'm working on a simple custom button that uses user supplied images as a background for the pressed and normal states. I've a lot of buttons so I decided to write a custom button and implement two properties for the pressed and normal states' pictures.
Here is the code I'm using
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);
}
}
}
I wrote the style for this button as follows
<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>
I tried a simple example
<Controls:ThemeableButton Style="{StaticResource ThemeableButtonTemplate}" x:Name="btnDidntNeedIt" NormalContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonUnselected}"
PressedContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonSelected}"
/>
but the image is not showing, I tried by removing the TemplateBinding from the style and replaced it with the relative source to the image file and it worked fine. I just don't wanna create a customized style for each button on the app. Any possible workaround?
I have encountered this before, TemplateBinding does not work for custom dependency properties on controls. See these related questions:
issues with template binding and binding of custom component
TemplateBinding does not work in certain cases(when using TranslateTransform)
I have always used this instead:
{Binding MyProperty, RelativeSource={RelativeSource TemplatedParent}}
It is semantically the same as TemplateBinding, and can also support value converters etc ...
这篇关于TemplateBinding来的DependencyProperty上的自定义控制不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!