根据属性值更改 VisualState

发布于 2024-10-17 22:54:08 字数 178 浏览 3 评论 0原文

如何根据 WP7 上的属性值更改 VisualState?

我尝试使用 MVVM 模式,当我的模型加载时,我希望我的视图进入特定的 VisualState。

在 Silverlight 中,我们有属性更改的触发器,但在 WP7 中没有!

PS:我不想使用框架我想了解它在WP7中是如何完成的。

How to change a VisualState based on a property value on WP7?

Im trying to use MVVM pattern and when my model is loading I want my view to go to especific VisualState.

In Silverlight we have triggers for property changes but in WP7 not!

PS: I dont want to use frameworks I want to understand how it is done in WP7.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无需解释 2024-10-24 22:54:08

我使用以下附加行为:

using System;
using System.Windows;
using System.Windows.Controls;

namespace PixelLab.WP7.Common.Behaviors
{
    /// 
    /// Provides an attached behavior for binding visual states.
    /// 
    public static class VisualStates
    {
        /// 
        /// Identifies the CurrentState attached property.
        /// 
        public static readonly DependencyProperty CurrentStateProperty = DependencyProperty
            .RegisterAttached(
                "CurrentState",
                typeof(string),
                typeof(VisualStates),
                new PropertyMetadata(TransitionToState));

        /// 
        /// Gets the current visual state of the specified object. This is an attached property. 
        /// 
        /// The source object.
        /// The current visual state of the specified object.
        public static string GetCurrentState(DependencyObject obj)
        {
            return (string)obj.GetValue(CurrentStateProperty);
        }

        /// 
        /// Sets the current visual state of the specified object. This is an attached property.
        /// 
        /// The target object.
        /// The new visual state.
        public static void SetCurrentState(DependencyObject obj, string value)
        {
            obj.SetValue(CurrentStateProperty, value);
        }

        static void startOnGuiThread( Action act )
        {
            var disp = Deployment.Current.Dispatcher;
            if( disp.CheckAccess() )
                act();
            else
                disp.BeginInvoke( act );
        }

        private static void TransitionToState( object sender, DependencyPropertyChangedEventArgs args )
        {
            FrameworkElement elt = sender as FrameworkElement;
            if( null == elt )
                throw new ArgumentException( "CurrentState is only supported on the FrameworkElement" );

            string newState = args.NewValue.ToString();
            startOnGuiThread( () => ExtendedVisualStateManager.GoToElementState( elt, newState, true ) );
        }
    }
}

在视图模型中,公开当前视觉状态的属性,然后在要处理视觉状态的视觉元素上使用以下内容来绑定视觉状态,例如

<phone:PhoneApplicationPage ...
    xmlns:common="clr-namespace:PixelLab.Common;assembly=PixelLab.Common"
    common:VisualStates.CurrentState="{Binding CurrentState}">

I use the following attached behavior:

using System;
using System.Windows;
using System.Windows.Controls;

namespace PixelLab.WP7.Common.Behaviors
{
    /// 
    /// Provides an attached behavior for binding visual states.
    /// 
    public static class VisualStates
    {
        /// 
        /// Identifies the CurrentState attached property.
        /// 
        public static readonly DependencyProperty CurrentStateProperty = DependencyProperty
            .RegisterAttached(
                "CurrentState",
                typeof(string),
                typeof(VisualStates),
                new PropertyMetadata(TransitionToState));

        /// 
        /// Gets the current visual state of the specified object. This is an attached property. 
        /// 
        /// The source object.
        /// The current visual state of the specified object.
        public static string GetCurrentState(DependencyObject obj)
        {
            return (string)obj.GetValue(CurrentStateProperty);
        }

        /// 
        /// Sets the current visual state of the specified object. This is an attached property.
        /// 
        /// The target object.
        /// The new visual state.
        public static void SetCurrentState(DependencyObject obj, string value)
        {
            obj.SetValue(CurrentStateProperty, value);
        }

        static void startOnGuiThread( Action act )
        {
            var disp = Deployment.Current.Dispatcher;
            if( disp.CheckAccess() )
                act();
            else
                disp.BeginInvoke( act );
        }

        private static void TransitionToState( object sender, DependencyPropertyChangedEventArgs args )
        {
            FrameworkElement elt = sender as FrameworkElement;
            if( null == elt )
                throw new ArgumentException( "CurrentState is only supported on the FrameworkElement" );

            string newState = args.NewValue.ToString();
            startOnGuiThread( () => ExtendedVisualStateManager.GoToElementState( elt, newState, true ) );
        }
    }
}

In your view model, expose a property for the current visual state, and then on the visual element that you want to handle the visual state for you use the following to bind the visual state, for example

<phone:PhoneApplicationPage ...
    xmlns:common="clr-namespace:PixelLab.Common;assembly=PixelLab.Common"
    common:VisualStates.CurrentState="{Binding CurrentState}">
温柔少女心 2024-10-24 22:54:08

最初,DataStateBehavior 行为看起来是完美匹配,这篇文章甚至专门讨论了使用用WP7就可以了

但是,本文引用的 Codeplex 项目不再具有该行为,并且该行为不在 Expression Blend 中(至少对于 WP7 项目而言)。

我倾向于在 ViewModel 上公开一个属性,并以编程方式侦听视图中的更改并相应地更改视觉状态:

在视图的构造函数中:

ViewModelLocator.MainViewModelStatic.PropertyChanged += ViewModelPropertyChanged;

然后创建一个相应更改状态的事件处理程序:

private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if(e.PropertyName == MainViewModel.SomeProp)
    {
        // Change the state using the VisualStateManager
    }
}

Damian

Initially the DataStateBehavior behavior looks to be a perfect match, and this article even specifically talks about using it with WP7.

However the Codeplex project the article references no longer has the behavior, and the behavior is not in Expression Blend (at least for WP7 projects).

I'd be inclined to expose a property on the ViewModel and programatically listen for changes in the View and change the Visual State accordingly:

In your View's constructor:

ViewModelLocator.MainViewModelStatic.PropertyChanged += ViewModelPropertyChanged;

Then create an event handler that changes the state accordingly:

private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if(e.PropertyName == MainViewModel.SomeProp)
    {
        // Change the state using the VisualStateManager
    }
}

Damian

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文