2011-02-15 172 views
4

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

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

在Silverlight中,我们触发了属性更改,但在WP7中没有! PS:我不想使用框架,我想了解它是如何在WP7中完成的。

+0

在后提到的问题并不是指MVVM,也不会改变visualstates或至少我没有看到连接时没有任何帮助。 – 2011-02-15 23:22:37

回答

8

我用下面附加的行为:

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}">
+0

每当我尝试在Windows Phone上使用该解决方案时,都会在页面初始化时出现ArgumentException。我找不到异常的来源:( – 2012-08-30 15:11:23

1

最初的DataStateBehavior行为看起来是一个完美的匹配,并且this article甚至会专门谈论与WP7一起使用它。

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

我倾向于对视图模型公开属性和编程听在查看更改并相应地改变可视状态:

在视图的构造函数:

ViewModelLocator.MainViewModelStatic.PropertyChanged += ViewModelPropertyChanged; 

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

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

达米安

+0

Derek的回答比较好,我已经提高了答案 - 如果有人搜索WP7和DataStateBehavior,我会离开我的答案 - 他们会发现Derek很酷的附加行为。 – Damian 2011-02-16 18:35:45