這聽起來像問題是,視圖模型依賴於視圖的生命週期 - 這自動意味着視圖將被通知的狀態轉換的視圖模型。目標是找到這些變化的最佳表現形式。
第一步是重新組織框架的互動:Start()
和Stop()
是必要的概念,我同意,確實感到沉重。相反,讓我們考慮一下我們作爲狀態機所做的事情。我會假設你的線程正在進行某種傾聽,所以我們的狀態可能是Listening
,Idle
和Complete
。它們將分別對應於正在運行的線程,暫停的線程和準備被終止的線程。
代表國家實實在在地是一個枚舉:
public enum ListenerState
{
Idle,
Listening,
Complete
}
您將宣佈這種類型的屬性在你的視圖模型:
public class ListenerModel : ViewModel
{
private ListenerState _state;
public ListenerState State
{
get { return _state; }
set
{
_state = value;
RaisePropertyChanged("State");
}
}
}
然後,你會聽的狀態變化並更新線程以匹配:
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
if(e.PropertyName == "State")
{
// Manipulate thread for current state
}
}
現在,視圖只需通知視圖的生命週期事件模型(一些視圖模型不可能不知道從視圖之外的任何其他方式):
private void OnLoaded(object sender, RoutedEventArgs e)
{
((ListenerModel) this.DataContext).State = ListenerState.Listening;
}
如果你想完全脫鉤從視圖模型視圖,您可以創建一個依賴屬性的爲國家控制:
public static readonly DependencyProperty ListenerStateProperty =
DependencyProperty.Register("ListenerState", typeof(ListenerState), typeof(YourControl), null);
public ListenerState ListenerState
{
get { return (ListenerState) GetValue(ListenerStateProperty); }
set { SetValue(ListenerStateProperty, value); }
}
然後,在Loaded
處理程序設置該屬性,而不是引用視圖模型的:
private void OnLoaded(object sender, RoutedEventArgs e)
{
this.ListenerState = ListenerState.Listening;
}
最後,你WOU ld將屬性綁定到標記中的視圖模型的屬性:
<local:YourControl ListenerState="{Binding State, Mode=TwoWay}" />