C# 实施";“关闭窗口”;使用MVVM的命令
因此,我的第一次尝试完全脱离了代码,现在我正试图按照MVVM信息的指导,重构代码以使用MVVM模式 我已经创建了一个viewmodel类来匹配我的view类,并且从命令开始将代码从代码中移到viewmodel中 我的第一个障碍是试图实现一个“关闭”按钮,如果数据没有被修改,它会关闭窗口。我已经装配了一个CloseCommand来替换“onClick”方法,除了代码尝试运行this.Close()之外,一切都很好。显然,由于代码已从窗口移动到普通类,“this”不是窗口,因此不可关闭。但是,根据MVVM,viewmodel不知道视图,因此我无法调用C# 实施";“关闭窗口”;使用MVVM的命令,c#,wpf,mvvm,relaycommand,C#,Wpf,Mvvm,Relaycommand,因此,我的第一次尝试完全脱离了代码,现在我正试图按照MVVM信息的指导,重构代码以使用MVVM模式 我已经创建了一个viewmodel类来匹配我的view类,并且从命令开始将代码从代码中移到viewmodel中 我的第一个障碍是试图实现一个“关闭”按钮,如果数据没有被修改,它会关闭窗口。我已经装配了一个CloseCommand来替换“onClick”方法,除了代码尝试运行this.Close()之外,一切都很好。显然,由于代码已从窗口移动到普通类,“this”不是窗口,因此不可关闭。但是,根据M
view.Close()
有人能建议我如何从viewmodel命令关闭窗口吗?我通过创建一个名为DialogResult的附加属性来实现:
公共静态类对话框关闭器
{
公共静态只读从属属性对话框ResultProperty=
DependencyProperty.RegisterAttached(
“DialogResult”,
类型(bool?),
类型(对话框闭合器),
新属性元数据(DialogResultChanged));
私有静态无效对话框ResultChanged(
依赖对象d,
DependencyPropertyChangedEventArgs(附件e)
{
var窗口=d作为窗口;
if(window!=null&(bool?)e.NewValue==true)
window.Close();
}
公共静态无效SetDialogResult(窗口目标,布尔值)
{
SetValue(DialogResultProperty,value);
}
}
然后在窗口标记中,将此内容写入XAML
WindowActions:DialogCloser.DialogResult="{Binding Close}"
最后在ViewModel中
private bool\u close;
公共厕所关闭
{
获取{return\u close;}
设置
{
如果(_close==值)
返回;
_关闭=值;
NotifyPropertyChanged(“关闭”);
}
}
如果将“关闭”更改为“真”,则窗口将关闭
Close = True;
不需要将视图实例传递到ViewModel图层。您可以像这样访问主窗口-
Application.Current.MainWindow.Close()
如上所述,我认为在ViewModel类中访问主窗口没有问题。根据MVVM原则,您的视图和ViewModel之间不应存在紧密耦合,即它们应在不考虑其他操作的情况下工作。这里,我们不从视图向ViewModel传递任何内容。如果您想寻找其他选项,这可能会对您有所帮助-我个人使用一种非常简单的方法:对于与可关闭视图相关的每个ViewModel,我创建了一个基本ViewModel,如下例所示:
公共抽象类CloseableViewModel
{
公共事件处理程序关闭请求;
受保护的void OnClosingRequest()
{
if(this.ClosingRequest!=null)
{
this.ClosingRequest(this,EventArgs.Empty);
}
}
}
然后在继承自CloseableViewModel
的ViewModel中,只需调用this.OnClosingRequest()代码>用于关闭
命令
他认为:
公共类视图
{
...
var vm=新的ClosableViewModel();
this.Datacontext=vm;
vm.ClosingRequest+=(发送方,e)=>this.Close();
}
单击按钮时从视图模型关闭窗口的解决方案如下:
视图模型
private ICommand _cancelCommand;
public ICommand CancelCommand
{
get
{
if (_cancelCommand == null)
{
_cancelCommand = new DelegateCommand<Window>(
x =>
{
x?.Close();
});
}
return _cancelCommand;
}
}
公共中继命令关闭窗口;
构造函数()
{
CloseWindow=新的中继命令(CloseWin);
}
公共无效关闭窗口(对象obj)
{
win窗口=obj作为窗口;
win.Close();
}
在视图中,设置如下
此解决方案快速简便。缺点是各层之间存在一些耦合
在viewmodel中:
public class CloseDialogMessage : NotificationMessage
{
public CloseDialogMessage(object sender) : base(sender, "") { }
}
private void OnClose()
{
Messenger.Default.Send(new CloseDialogMessage(this));
}
公共类MyWindowViewModel:ViewModelBase
{
public命令。标准命令CloseCommand
{
得到
{
返回新命令。标准命令(关闭);
}
}
公众假期结束()
{
foreach(System.Windows.Application.Current.Windows中的System.Windows.Window窗口)
{
if(window.DataContext==此)
{
window.Close();
}
}
}
}
这与eoldre的答案非常相似。它在功能上是相同的,因为它通过相同的Windows集合查找具有视图模型作为其datacontext的窗口;但是我使用了一个RelayCommand和一些LINQ来实现相同的结果
public RelayCommand CloseCommand
{
get
{
return new RelayCommand(() => Application.Current.Windows
.Cast<Window>()
.Single(w => w.DataContext == this)
.Close());
}
}
public RelayCommand close命令
{
得到
{
返回新的RelayCommand(()=>Application.Current.Windows
.Cast()
.Single(w=>w.DataContext==this)
.Close());
}
}
这是来自ken2k的答案(谢谢!),只需将CloseCommand
也添加到基础CloseableViewModel
public class CloseableViewModel
{
public CloseableViewModel()
{
CloseCommand = new RelayCommand(this.OnClosingRequest);
}
public event EventHandler ClosingRequest;
protected void OnClosingRequest()
{
if (this.ClosingRequest != null)
{
this.ClosingRequest(this, EventArgs.Empty);
}
}
public RelayCommand CloseCommand
{
get;
private set;
}
}
您的视图模型将继承它
public class MyViewModel : CloseableViewModel
那么在你看来
public MyView()
{
var viewModel = new StudyDataStructureViewModel(studyId);
this.DataContext = viewModel;
//InitializeComponent(); ...
viewModel.ClosingRequest += (sender, e) => this.Close();
}
请给我一条路 简短描述
使用MVVM light toolkit: 在ViewModel中:
public void notifyWindowToClose()
{
Messenger.Default.Send<NotificationMessage>(
new NotificationMessage(this, "CloseWindowsBoundToMe")
);
}
public void notifyWindowToClose()
{
Messenger.Default.Send(
新通知消息(此“CloseWindowsBoundToMe”)
);
}
并且认为:
Messenger.Default.Register<NotificationMessage>(this, (nm) =>
{
if (nm.Notification == "CloseWindowsBoundToMe")
{
if (nm.Sender == this.DataContext)
this.Close();
}
});
Messenger.Default.Register(此,(nm)=>
{
如果(nm.Notification==“CloseWindowsBoundToMe”)
{
if(nm.Sender==this.DataContext)
这个。关闭();
}
});
MVVM灯带有自定义消息通知,以避免窗口处理每个通知消息
在视图模式下
public class ViewModel
{
public Action CloseAction { get; set; }
private void CloseCommandFunction()
{
CloseAction();
}
}
public partial class DialogWindow : Window
{
public DialogWindow()
{
ViewModel vm = new ViewModel();
this.DataContext = vm;
vm.CloseAction = new Action(() => this.Close());
}
}
x:Name="AboutViewWindow"
CommandParameter="{Binding ElementName=AboutViewWindow}"
Command="{Binding CancelCommand}"
private ICommand _cancelCommand;
public ICommand CancelCommand
{
get
{
if (_cancelCommand == null)
{
_cancelCommand = new DelegateCommand<Window>(
x =>
{
x?.Close();
});
}
return _cancelCommand;
}
}