我正在尝试创建一个派生自Button的CustomControl,它只显示为彩色矩形。我想在我的控件上设置两个属性,指定正常颜色(ColdColor),以及鼠标悬停在控件上时使用的另一种颜色(HotColor)。
我无法弄清楚如何在画笔颜色和控件属性之间设置绑定。这是我的代码:
Generic.xaml:
<Style TargetType="{x:Type local:TestCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TestCustomControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Name="MyBorder">
<Border.Background>
<!-- This works: -->
<!--<SolidColorBrush Color="Green" />-->
<!-- This doesn't work: -->
<SolidColorBrush Color="{TemplateBinding ColdColor}" />
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<!-- This works: -->
<!--<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="Red" Duration="0:0:0.2"/>-->
<!-- This doesn't work: -->
<ColorAnimation Storyboard.TargetProperty="Background.Color" Storyboard.TargetName="MyBorder" To="{TemplateBinding HotColor}" Duration="0:0:0.2"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TestCustomControl.cs:
public class TestCustomControl : Button
{
static TestCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl)));
}
public Color HotColor
{
get { return (Color)GetValue(HotColorProperty); }
set { SetValue(HotColorProperty, value); }
}
// Using a DependencyProperty as the backing store for HotColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HotColorProperty =
DependencyProperty.Register("HotColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(new Color()));
public Color ColdColor
{
get { return (Color)GetValue(ColdColorProperty); }
set { SetValue(ColdColorProperty, value); }
}
// Using a DependencyProperty as the backing store for ColdColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ColdColorProperty =
DependencyProperty.Register("ColdColor", typeof(Color), typeof(TestCustomControl), new UIPropertyMetadata(new Color()));
}
MainWindow.xaml中的用法:
<my:TestCustomControl ColdColor="#FF0000AF" HotColor="#FFFF00AF"/>
编辑:说“不起作用”意味着TestCustomControl完全透明。
答案 0 :(得分:3)
没有明显的问题(afaik),我会更改这段代码:
UIPropertyMetadata(new Color())
到
UIPropertyMetadata(Colors.White)
并查看它的'new Color()'是否是问题
编辑 -
如果上述方法无效,请尝试更改此
<SolidColorBrush Color="{TemplateBinding ColdColor}" />
到这个
<SolidColorBrush Color="{Binding
RelativeSource={RelativeSource TemplatedParent},
Path=ColdColor}" />
答案 1 :(得分:0)
可视状态管理器有一个相关的限制:它无法使用绑定设置的属性设置动画。所以你只是想做一些无法做到的事情。
您可以做的是复制元素并使用不透明度进行转换。以下显示了如何使用VSM和不透明度执行此操作:
给定具有依赖属性的自定义控件TwoColorBox
Color ColorOne
Color ColorTwo
并以视觉状态:
ColorOne
ColorTwo
以下控制模板可以根据需要执行,不使用透明度渗透
<ControlTemplate TargetType="{x:Type view:TwoColorBox}">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ColorStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="ColorOne"/>
<VisualState x:Name="ColorTwo">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="borderTwo">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="borderOne"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.BorderBrush>
<SolidColorBrush
Color="{Binding ColorOne, RelativeSource={RelativeSource TemplatedParent}}"/>
</Border.BorderBrush>
</Border>
<Border
x:Name="borderTwo"
BorderThickness="{TemplateBinding BorderThickness}" Opacity="0">
<Border.BorderBrush>
<SolidColorBrush
Color="{Binding ColorTwo, RelativeSource={RelativeSource TemplatedParent}}"/>
</Border.BorderBrush>
</Border>
</Grid>
</ControlTemplate>