2011-02-15 71 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