2012-09-02 2 views
0

나는 radOutlookbar를 사용하여 화면에 다른 데이터 세트 (사용자, 국적 등)를 표시하는 응용 프로그램을 가지고 있습니다. 문제없이 데이터를 표시하려면 각 항목에 필요한보기를로드 할 수 있어야합니다.Visual State Manager를 사용하여보기/숨기기 silverlight & PRISM

그런 다음 표시된 데이터 집합 내에서 각 선택된 항목 (즉, 사용자)에 대한 세부 정보를 표시하기 위해 각 데이터 집합 (사용자, 국적 등)에 대한보기를 작성했습니다.

사례 : 먼저 항목을 클릭하면 각 데이터 집합에 대한 각각의보기를 표시해야합니다. 둘째, 표시된보기에는 표시된 세부 사항을 편집/추가하는 옵션이 있습니다.

상태 기반 탐색을 사용하여이 시나리오를 달성하고 싶습니다.

그래서 로드 된 뷰를 호스팅하는 그리드의 ItemsPanelTemplate이있는 ItemsControl 내에 PRISM 영역이 있습니다. 기본적으로 각 데이터 집합의 뷰를로드합니다.

질문, 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에서이 같이 당신의 ViewModel에 첨부 :

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

이제 XAML에서 VSM은 ViewModelBase에 ViewModelVisualState 속성에 바인딩 (또는 무엇 이 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

관련 문제