110,536
社区成员
发帖
与我相关
我的任务
分享
public class MainWindowViewModel : Z.Core.WPF.NotificationObject
{
private readonly Window window;
public MainWindowViewModel(Window win)
{
this.window = win;
Init();
}
}
public MainWindow()
{
this.DataContext = new ViewModel.MainWindowViewModel(this);
InitializeComponent();
}
public ICommand OnClose { get; set; }
public void Close(EventArgs e)
{
if (Service.ServiceClient.Instance != null)
{
Service.ServiceClient.Instance.Leave();
Service.ServiceClient.Instance.Close();
Service.ServiceClient.Instance = null;
}
//this.window.Close();
}
public class SomeWindow: ChildWindow
{
private SomeViewModel _someViewModel;
public SomeWindow()
{
InitializeComponent();
this.Loaded += SomeWindow_Loaded;
this.Closed += SomeWindow_Closed;
}
void SomeWindow_Loaded(object sender, RoutedEventArgs e)
{
_someViewModel = this.DataContext as SomeViewModel;
_someViewModel.PropertyChanged += _someViewModel_PropertyChanged;
}
void SomeWindow_Closed(object sender, System.EventArgs e)
{
_someViewModel.PropertyChanged -= _someViewModel_PropertyChanged;
this.Loaded -= SomeWindow_Loaded;
this.Closed -= SomeWindow_Closed;
}
void _someViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == SomeViewModel.DialogResultPropertyName)
{
this.DialogResult = _someViewModel.DialogResult;
}
}
}
<Button Content="关闭" Name="btnLeave" Height="23" FontSize="10">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<!-- 调用Window.Close会触发Closed事件,自动执行后台的OnClose命令 -->
<ei:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" MethodName="Close" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
如果不忌讳写在code behind类中的话,可以这样:
public MainWindow()
{
this.DataContext = new ViewModel.MainWindowViewModel();
InitializeComponent();
this.btnLeave.Click += (o, args) => this.Close(); // 同样会自动触发执行OnClose命令
}
另外,我觉得特殊情况下,只要不违反MVVM总的原则,传个参数就传了,没什么了不起。
只不过作为构造参数传进去,ViewModel所有的地方都能访问到UI,影响太大。
可以把window作为Command的参数传过去,缩小它的作用范围:
<Button Content="关闭" Name="btnLeave" Height="23" FontSize="10"
Command="{Binding OnClose}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
后台的OnClose命令现在被两处调用(Button.Command和Window.Closed),所以要修改下:
public void Close(object e)
{
// 这是从Window.Closed事件调用过来的
if (e is EventArgs)
{
if (Service.ServiceClient.Instance != null)
{
Service.ServiceClient.Instance.Leave();
Service.ServiceClient.Instance.Close();
Service.ServiceClient.Instance = null;
}
}
else if (e is Window) // 这是从Button.Command事件调用过来的
(e as Window).Close(); // 这里会再自动触发Window.Closed事件
}
上面这种做法不能让正统的MVVM人士看到,因为不够纯正。