开发者

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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜