一个新手问题,但我无法让它发挥作用。在尝试使用SO "How Should the View Model Close the form" 的答案时,我将UserControl定义为:
<UserControl
.....
h:DialogCloser.DialogResult="{Binding DialogResult}"
>
在设计时显示:
Property 'DialogResult' is not attachable to elements of type 'UserControl'.
DialogCloser定义为:
public static class DialogCloser
{
public static readonly DependencyProperty DialogResultProperty =
DependencyProperty.RegisterAttached(
"DialogResult",
typeof(bool?),
typeof(DialogCloser),
new PropertyMetadata(DialogResultChanged));
private static void DialogResultChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null)
window.DialogResult = e.NewValue as bool?;
}
public static void SetDialogResult(Window target, bool? value)
{
target.SetValue(DialogResultProperty, value);
}
}
UserControl由以下方式打开:
var win = new WindowDialog();
win.Title = title;
win.DataContext = datacontext;
return win.ShowDialog();
在UserControl的View Model中,我有:
public new void DoExit()
{
DialogResult = true;
}
private bool? dialogresult;
public bool? DialogResult
{
get
{
return dialogresult;
}
set
{
if (dialogresult != value)
{
dialogresult = value;
OnPropertyChanged("DialogResult");
}
}
}
使用DoExit()时,模态对话框(我的UserControl) 不 关闭。怎么了?我如何让设计师(VS 2010)不抛出错误?
感谢您的帮助。
附录:
public class ModalDialogService : IModalDialogService
{
public bool? ShowDialog(string title, object datacontext)
{
var win = new WindowDialog();
win.Title = title;
win.DataContext = datacontext;
return win.ShowDialog();
}
}
注意:如果“UserControl”更像是“Window”,设计师很高兴,但错误是:
"Window must be the root of the tree. Cannot add Window as a child of Visual."
帮助某人?
答案 0 :(得分:2)
我是新手,但把所有东西放在一起,我会建议这是像我这样的新手的可能答案。
这是否符合最佳MVVM做法?
首先,正如设计师所说&#34; Property&#39; DialogResult&#39;不能附加到&#39; UserControl&#39;。
类型的元素我的翻译,&#34;控制&#34;不是一个窗口 - 因此它无法关闭。因此,
h:DialogCloser.DialogResult="{Binding DialogResult}"
错了。删除它。
其次,我的usercontrol被显示为另一个普通窗口的唯一元素
<Window x:Class="Nova5.UI.Views.Ink.WindowDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowDialog"
WindowStyle="SingleBorderWindow"
WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">
<ContentPresenter x:Name="DialogPresenter" Content="{Binding .}"/>
</Window>
现在,当最顶层的视图模型
时,整个事情就会启动 var dialog = new WindowDialog
{
Title = "It's me Margaret",
ShowInTaskbar = false,
Topmost = true,
ResizeMode = ResizeMode.NoResize
};
dialog.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
ModalDialogService dialogService = new ModalDialogService();
dialogService.ShowDialog<PrescriptionWriterViewModel>(dialog,
new PrescriptionWriterViewModel(),
returnedViewModelInstance =>
{
if (dialog.DialogResult.HasValue && dialog.DialogResult.Value)
{
}
}
);
};
当在usercontrol上单击Exit时,它在其视图模型中通过DelegateCommand执行
public new void DoExit()
{
OnRequestClose();
}
public event EventHandler RequestClose;
void OnRequestClose()
{
EventHandler handler = this.RequestClose;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
然后在启动对话服务
中处理此关闭请求public void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose)
{
view.DataContext = viewModel;
IDialogViewModel vm = viewModel as IDialogViewModel;
if (vm !=null)
vm.RequestClose += (s,e)=> view.Close(); //RequestClose is the event in the ViewModel that the view will listen for.
if (onDialogClose != null)
{
view.Closed += (sender, e) => onDialogClose(viewModel);
}
view.Show();
}
当视图关闭时,onDialogClose(viewModel)然后回调到最顶层的视图模型并完成用
指定的操作 returnedViewModelInstance =>
{
if (dialog.DialogResult.HasValue && dialog.DialogResult.Value)
{
}
}
完成几个小时的学习。我希望它对某人有用。