WPF ControlTemplate with VisualStates
I want to create a ControlTemplate with predefined VisualStates. I want to use 开发者_JAVA技巧them with GoToStateActions and DataTriggers.
I don't know what exactly is going wrong here. It seems to me, that the Binding isn't established in that way I suppose it is.
namespace ControlTemplateVisualState
{
using System.Windows.Controls;
public class MyControl : ContentControl
{
public MyControl()
{
this.DefaultStyleKey = typeof(MyControl);
}
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ControlTemplateVisualState="clr-namespace:ControlTemplateVisualState"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions">
<ControlTemplate x:Key="MyControlTemplate" TargetType="{x:Type ControlTemplateVisualState:MyControl}">
<Grid x:Name="grid" Background="Red">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="IsDisabledState">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
<EasingColorKeyFrame KeyTime="0" Value="#FF2BFF00"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding IsEnabled, ElementName=grid}" Value="False">
<ei:GoToStateAction StateName="IsDisabledState"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type ControlTemplateVisualState:MyControl}">
<Setter Property="Background" Value="#FF0010FF"/>
<Setter Property="Template" Value="{StaticResource MyControlTemplate}"/>
</Style>
</ResourceDictionary>
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlTemplateVisualState.MainWindow"
x:Name="Window"
xmlns:local="clr-namespace:ControlTemplateVisualState"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<local:MyControl IsEnabled="False"/>
</Grid>
</Window>
You could give this a go:
<i:Interaction.Behaviors>
<si:DataStateBehavior Binding='{Binding IsLoggedIn}' Value='True'
TrueState='LoggedInState' FalseState='LoggedOutState'/>
</i:Interaction.Behaviors>
It's slightly different, but works even with Silverlight, see: http://expressionblend.codeplex.com/wikipage?title=Behaviors%20and%20Effects&referringTitle=Documentation
Just make sure to get the fixed version if you use WPF4: http://expressionblend.codeplex.com/workitem/8148
I don't think Blend SDK triggers and behaviors can be used in control templates -- only in UserControls: there's no concrete object to which the trigger can be attached when the XAML is parsed. (I'm not 100% certain of this explanation, but I do know that if you have multiple control templates, you can't put Blend behaviors in all of them.) You'll need code behind to invoke the VSM -- that's just how custom controls work. You'll use something like this code from the Silverlight Toolkit:
public static void GoToState(Control control, bool useTransitions, params string[] stateNames)
{
foreach (var name in stateNames)
{
if (VisualStateManager.GoToState(control, name, useTransitions))
break;
}
}
精彩评论