2012-09-02 58 views
0

我有一個應用程序使用radOutlookbar在屏幕上顯示不同的數據集(用戶,國籍等)。 我已經設法加載每個項目中所需的視圖來顯示沒有問題的數據。使用視覺狀態管理器顯示/隱藏視圖silverlight&PRISM

然後,我爲每個數據集(用戶,國籍等)構建了視圖,以在顯示的數據集內顯示每個選定項目(即:用戶)的詳細信息。

案例: 首先,當我點擊它的項目時,我需要顯示每個數據集的相應視圖。 二,顯示的視圖將有一個選項來編輯/添加顯示的細節。

我想使用基於狀態的導航來實現這個場景。

因此, 我在ItemsControl中有一個PRISM區域,用網格的ItemsPanelTemplate來承載加載的視圖,基本上我加載了每個數據集的視圖。

問題, 如何根據所選數據集使用VSM顯示/隱藏相應視圖?

問題2: 我應該能夠在加載的視圖內定義另一個嵌套狀態來啓用編輯/添加每個視圖的詳細信息嗎?

如果有人有任何想法做到這一點,將有很大的幫助,有一個起始代碼。 此致敬禮

回答

0

可能還有其他方案來訪問VSM,但我更喜歡爲它創建AttachedProperty。讓我解釋。

這裏的VisualState經理

/// <summary> 
/// Class will allow to change VisualSate on ViewModel via attached properties 
/// </summary> 
public static class VisualStateManagerEx 
{ 
    private static PropertyChangedCallback callback = new PropertyChangedCallback(VisualStateChanged); 

    /// <summary> 
    /// Gets the state of the visual. 
    /// </summary> 
    /// <param name="obj">The obj.</param> 
    /// <returns></returns> 
    public static string GetVisualState(DependencyObject obj) 
    { 
     return (string)obj.GetValue(VisualStateProperty); 
    } 

    /// <summary> 
    /// Sets the state of the visual. 
    /// </summary> 
    /// <param name="obj">The obj.</param> 
    /// <param name="value">The value.</param> 
    public static void SetVisualState(DependencyObject obj, string value) 
    { 
     obj.SetValue(VisualStateProperty, value); 
    } 

    /// <summary> 
    /// DP for 'VisualState' 
    /// </summary> 
    public static readonly DependencyProperty VisualStateProperty = 
     DependencyProperty.RegisterAttached(
      "VisualState", 
      typeof(string), 
      typeof(VisualStateManagerEx), 
      new PropertyMetadata(null, VisualStateManagerEx.callback) 
     ); 

    /// <summary> 
    /// Visuals the state changed. 
    /// </summary> 
    /// <param name="d">The d.</param> 
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    public static void VisualStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     //Control changeStateControl = d as Control; 
     FrameworkElement changeStateControl = d as FrameworkElement; 
     if (changeStateControl == null) 
      throw (new Exception("VisualState works only on Controls type")); 

     if (Application.Current.Dispatcher.CheckAccess() == false) 
     { 
      // Wrong thread 
      System.Diagnostics.Debug.WriteLine("[VisualStateManagerEx] 'VisualStateChanged' event received on wrong thread -> re-route via Dispatcher"); 
      Application.Current.Dispatcher.BeginInvoke(
       //() => { VisualStateChanged(d, e); } 
       VisualStateManagerEx.callback 
       , new object[] { d, e }); //recursive 
     } 
     else 
     { 
      if (string.IsNullOrEmpty(e.NewValue.ToString()) == false) 
      { 
       //VisualStateManager.GoToState(changeStateControl, e.NewValue.ToString(), true); 
       VisualStateManager.GoToElementState(changeStateControl, e.NewValue.ToString(), true); 
       System.Diagnostics.Debug.WriteLine("[VisualStateManagerEx] Visual state changed to " + e.NewValue.ToString()); 
      } 
     } 
    } 
} 

現在 - 在XAML你把它連接到您的視圖模型是這樣的:

<UserControl 
    xmlns:VSManagerEx=clr-namespace:Namespace.namespace;assembly=Assembly01" 
    VSManagerEx:VisualStateManagerEx.VisualState="{Binding Path=ViewModelVisualState, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    ... 
    ... 

現在你在XAML VSM勢必ViewModelVisualState財產ViewModelBase(或任何將被綁定到此UserControlDataContext。所以實際上你使用的ViewModelBase是這樣的:

/// <summary> 
/// Base class for all 'view-models' 
/// </summary> 
[Export(typeof(ViewModelBase))] 
public abstract class ViewModelBase : INavigationAware, INotifyPropertyChanged 
{ 
    private SynchronizationContext parentSyncContent; 

    #region VisualState 
    private string viewModelVisualState = string.Empty; 
    /// <summary> 
    /// Gets or sets the state of the view model visual. 
    /// </summary> 
    /// <value> 
    /// The state of the view model visual. 
    /// </value> 
    public virtual string ViewModelVisualState 
    { 
     get { return viewModelVisualState; } 
     set 
     { 
      viewModelVisualState = value; 
      RaisePropertyChanged(this, "ViewModelVisualState"); 
     } 
    } 
    #endregion 

    /// <summary> 
    /// Raises the property changed. 
    /// </summary> 
    /// <param name="Sender">The sender.</param> 
    /// <param name="PropertyName">Name of the property.</param> 
    public void RaisePropertyChanged(object Sender, string PropertyName) 
    { 
     parentSyncContent.Post((state) => 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(Sender, new PropertyChangedEventArgs(PropertyName)); 
     }, null); 
    } 


    ... 
    ... 

所以 - 在此ViewModelBase繼承任何視圖模型可以宣佈它自己的VMS狀態和這樣的管理它們:

[Export(typeof(IViewModel1)) 
    public ViewModel1 : ViewModelBase, IViewModel1 
    { 

      private const string VM_STATE_WORKING = "WorkingState"; 

      internal void StartWorking() 
      { 
       this.ViewModelVisualState = VM_STATE_WORKING; 
    ... 
    ... 

問候問題2:沒有 - 你不需要申報中做任何事任何補充意見。閱讀有關導航的PRISM文檔。有很多關於如何創建支持各種表示邏輯的View/ViewModel的例子。

對您有幫助嗎?

+0

謝謝Jasper,我已經使用了「DataStateBehavior」,它的工作原理如下:當然,你需要混合才能工作。 – Waleed