无法关闭附加属性(MVVM)的模式对话框



这是一个新手问题,但我无法解决。在尝试使用SO"视图模型应如何关闭窗体"的答案时,我有一个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的视图模型中,我有:

public new void DoExit()
    {
        DialogResult = true;
    }
    private bool? dialogresult;
    public bool? DialogResult
    {
        get
        {
            return dialogresult;
        }
        set
        {
            if (dialogresult != value)
            {
                dialogresult = value;
                OnPropertyChanged("DialogResult");
            }
        }
    }

使用DoExit()时,模式对话框myUserControl不会关闭。怎么了?我如何让设计者(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."

帮助别人?

我对此很陌生,但综合来看,我建议这是像我这样的新手的一个可能答案。

这是否符合MVVM的最佳实践?

首先,正如设计者所说"属性"DialogResult"不可附加到"UserControl"类型的元素

我的翻译是,"控件"不是一个窗口,所以它不能关闭。因此,

h:DialogCloser.DialogResult="{Binding DialogResult}"

是错误的。移除它。

其次,我的用户控件被显示为这样一个普通窗口的唯一元素

 <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)
                                {
                                 }
                     }
                );
        };

当在用户控件上单击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)
                                {
                                 }
                     }

这样就完成了几个小时紧张的学习。我希望它对某些人有用。

相关内容

  • 没有找到相关文章

最新更新