这听起来像问题是,视图模型依赖于视图的生命周期 - 这自动意味着视图将被通知的状态转换的视图模型。目标是找到这些变化的最佳表现形式。
第一步是重新组织框架的互动: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}" />