我的解決方案與Graeme Bradbury的類似,但我不使用DataStateSwitchBehavior,因爲如果我的X控件放置在選項卡面板(或類似的東西)中,並且狀態在另一個選項卡上發生變化,會得到一個異常('元素'沒有找到..)。拋出異常是因爲我在另一個選項卡上卸載了我的X控件,並且未找到需要更新的元素。
因此,這裏是我做的:
在我的視圖模型我有發送通知消息的屬性的VisualState當狀態改變(我用MVVM light toolkit):
private string visualState = XVisualStates.InitialState;
public string VisualState
{
get
{
return visualState;
}
set
{
visualState = value;
Messenger.Default.Send(new XStateChangedMessage(value));
}
}
,並在我看來代碼後面我訂閱通知:
public partial class XControl : UserControl
{
private string visualState = XVisualStates.InitialState;
public XControl()
{
InitializeComponent();
//go to state when view is loaded
Loaded += (s, e) => ChangeState(); //every time a view is loaded go to current state
//change visual state when a notification is received
Messenger.Default.Register<XStateChangedMessage>(this,
state =>
{
visualState = state.CurrentState; //save current state
ChangeState();
});
}
void ChangeState()
{
try
{
VisualStateManager.GoToState(this, visualState, true); //will throw an exception if current view is unloaded
}
catch
{
//NOTE: supress 'element' not found errors if user navigated to another view and state changes
}
}
}
和XStateChangedMessage是一個簡單的類:
public class XStateChangedMessage
{
public string CurrentState { get; private set; }
public XStateChangedMessage (string currentState)
{
CurrentState = currentState;
}
}
那麼我可以在我的控件上定義視覺狀態(也在子窗口上?),然後使用DataStateSwitchBehavior切換它們?例如,一個州可能是'SearchInProgress'。那麼我該如何使用VSM來禁用該按鈕,以便在控件位於「SearchInProgress」中時該按鈕不可點擊? – 2010-02-23 12:30:40
謝謝格雷姆。我得到這個在一個示例項目中工作,看起來這是一條路。但是,我似乎遇到了同樣的問題在這裏提到:http://stackoverflow.com/questions/2118814/how-can-i-use-visualstates-in-a-childwindow。 VSM似乎不適用於子窗口。我現在將把所有內容放在UserControl中並在子窗口中引用它。 我正在使用您提到的DataStateSwitcher使其成爲ViewModel驅動。 – 2010-02-23 14:47:00