C# 使用MVVM设计模式创建新窗口的最佳方法是什么

C# 使用MVVM设计模式创建新窗口的最佳方法是什么,c#,wpf,windows,mvvm,C#,Wpf,Windows,Mvvm,我想问一下,使用MVVM模式和MVVMLight框架显示子窗口的最佳方式是什么。我在这个网站上读了几篇文章,但我似乎不理解所写的代码到底在做什么,所以请提供一个详细的解释和你的想法 我使用服务显示新窗口或新对话框 您可以查看我的第一个版本中的对话框 在过去的几天里,我给我的界面添加了更多的重载 public interface IUIDialogWindowService { ///<summary> /// Zeigt ein Dialog an. ///&

我想问一下,使用MVVM模式和MVVMLight框架显示子窗口的最佳方式是什么。我在这个网站上读了几篇文章,但我似乎不理解所写的代码到底在做什么,所以请提供一个详细的解释和你的想法

我使用服务显示新窗口或新对话框

您可以查看我的第一个版本中的对话框

在过去的几天里,我给我的界面添加了更多的重载

public interface IUIDialogWindowService
{
    ///<summary>
    /// Zeigt ein Dialog an.
    ///</summary>
    ///<param name="titel">Titel für den Dialog</param>
    ///<param name="datacontext">DataContext für den Dialog</param>
    ///<returns>true wenn DialogResult=true, ansonsten false</returns>
    bool? ShowDialog(string titel, object datacontext);

    ///<summary>
    /// Zeigt ein Dialog an.
    ///</summary>
    ///<param name="titel">Titel für den Dialog</param>
    ///<param name="datacontext">DataContext für den Dialog</param>
    ///<param name="minHeigth">Minimum Height</param>
    ///<param name="minWidth">Minimum Width</param>
    ///<param name="maxHeigth">Maximum Height</param>
    ///<param name="maxWidth">Maximum Width</param>
    ///<returns>true wenn DialogResult=true, ansonsten false</returns>
    bool? ShowDialog(string titel, object datacontext, double minHeigth = 0, double minWidth=0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity);


    /// <summary>
    /// Zeigt ein Dialog an
    /// </summary>
    /// <param name="titel">Titel für den Dialog<</param>
    /// <param name="datacontext">DataContext für den Dialog</param>
    /// <param name="settings">ApplicationsSetting für Height and Width</param>
    /// <param name="pathHeigthSetting">Name für Height Setting</param>
    /// <param name="pathWidthSetting">Name für Width Setting</param>
    /// <param name="minHeigth">Minimum Height</param>
    /// <param name="minWidth">Minimum Width</param>
    /// <param name="maxHeigth">Maximum Height</param>
    /// <param name="maxWidth">Maximum Width</param>
    /// <returns>true wenn DialogResult=true, ansonsten false</returns>
    bool? ShowDialog(string titel, object datacontext, ApplicationSettingsBase settings, string pathHeigthSetting, string pathWidthSetting, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity);
}


///<summary>
/// Implementierung von <see cref="IUIDialogWindowService"/>
///</summary>
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IUIDialogWindowService))]
public class WpfUIDialogWindowService : IUIDialogWindowService
{
    #region Implementation of IUIDialogWindowService

    ///<summary>
    /// Zeigt ein Dialog an.
    ///</summary>
    ///<param name="titel">Titel für den Dialog</param>
    ///<param name="datacontext">DataContext für den Dialog</param>
    ///<returns>true wenn DialogResult=true, ansonsten false</returns>
    public bool? ShowDialog(string titel, object datacontext)
    {
        var win = new DialogWindow {Title = titel, DataContext = datacontext};

        return win.ShowDialog();
    }

    ///<summary>
    /// Zeigt ein Dialog an.
    ///</summary>
    ///<param name="titel">Titel für den Dialog</param>
    ///<param name="datacontext">DataContext für den Dialog</param>
    ///<param name="minHeigth">Minimum Height</param>
    ///<param name="minWidth">Minimum Width</param>
    ///<param name="maxHeigth">Maximum Height</param>
    ///<param name="maxWidth">Maximum Width</param>
    ///<returns>true wenn DialogResult=true, ansonsten false</returns>
    public bool? ShowDialog(string titel, object datacontext, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity)
    {
        var win = new DialogWindow { Title = titel, DataContext = datacontext };

        win.MinHeight = minHeigth;
        win.MinWidth = minWidth;
        win.MaxHeight = maxHeigth;
        win.MaxWidth = maxWidth;

        return win.ShowDialog();
    }

    /// <summary>
    /// Zeigt ein Dialog an
    /// </summary>
    /// <param name="titel">Titel für den Dialog<</param>
    /// <param name="datacontext">DataContext für den Dialog</param>
    /// <param name="settings">ApplicationsSetting für Height and Width</param>
    /// <param name="pathHeigthSetting">Name für Height Setting</param>
    /// <param name="pathWidthSetting">Name für Width Setting</param>
    /// <param name="minHeigth">Minimum Height</param>
    /// <param name="minWidth">Minimum Width</param>
    /// <param name="maxHeigth">Maximum Height</param>
    /// <param name="maxWidth">Maximum Width</param>
    /// <returns>true wenn DialogResult=true, ansonsten false</returns>
    public bool? ShowDialog(string titel, object datacontext, ApplicationSettingsBase settings, string pathHeigthSetting, string pathWidthSetting, double minHeigth = 0, double minWidth = 0, double maxHeigth = double.PositiveInfinity, double maxWidth = double.PositiveInfinity)
    {
        var win = new DialogWindow { Title = titel, DataContext = datacontext };

        win.MinHeight = minHeigth;
        win.MinWidth = minWidth;
        win.MaxHeight = maxHeigth;
        win.MaxWidth = maxWidth;

        try
        {
            if(settings != null)
            {
                win.SizeToContent = SizeToContent.Manual;

                var height = settings[pathHeigthSetting];
                var width = settings[pathWidthSetting];

                BindingOperations.SetBinding(win, FrameworkElement.HeightProperty, new Binding(pathHeigthSetting) { Source = settings, Mode = BindingMode.TwoWay });
                BindingOperations.SetBinding(win, FrameworkElement.WidthProperty, new Binding(pathWidthSetting) { Source = settings, Mode = BindingMode.TwoWay });

                win.Height = (double)height;
                win.Width = (double)width;
            }
        }
        catch
        {
            win.SizeToContent = SizeToContent.WidthAndHeight;
        }

        return win.ShowDialog();
    }





    #endregion
}
公共接口IUIDialogWindowService
{
///
///齐格特·伊恩对话。
///
///蒂特尔·弗尔登对话
///DataContext für den对话框
///true wenn DialogResult=true,ansonsten false
bool?ShowDialog(字符串滴度、对象数据上下文);
///
///齐格特·伊恩对话。
///
///蒂特尔·弗尔登对话
///DataContext für den对话框
///最小高度
///最小宽度
///最大高度
///最大宽度
///true wenn DialogResult=true,ansonsten false
bool?ShowDialog(字符串滴度,对象数据上下文,双最小高度=0,双最小宽度=0,双最大高度=double.PositiveInfinity,双最大宽度=double.PositiveInfinity);
/// 
///对话
/// 

///Titel für den Dialog首先是一个问题,也是一个违反直觉的问题。打开新窗口动作与MVVM有什么关系

我个人认为根本没有任何联系。事实上,就像其他几个UI构造一样,它完全发生在视图层。还有其他几个类似的概念

  • 一个基于导航的界面(使用NavigationWindow),在该界面中,数据被填充到表单中,然后按下
    Next
    ,以切换到下一页
  • 打开时包含一组可变操作的上下文菜单
  • 动态加载活动页的选项卡式控件
所有这些都是向用户显示新视图的不同方式。所有这些都仅通过显示绑定到ViewModels的新UI元素而存在于视图层中

然而,有许多围绕MVVM发展的模式支持这一点。通常,这是使用服务或控制器来处理视图操作,请检查您选择的MVVM库是否支持显示新视图的方式

最后,有一件事让我感到困惑,那就是当你需要执行一个操作并更改视图时会发生什么。通常你会绑定UI对象(例如一个按钮)添加到ViewModel级别的命令以执行操作,并依靠绑定来更新显示新值的UI控件。由于ViewModel不应该知道视图,因此任何更改UI的操作都必须仅在视图中进行。这意味着您无法绑定到ViewModel命令。幸运的是,您可以在视图中创建命令委托给视图模型级操作并更改UI的级别


(嗯……回过头来看,不确定这是否回答了问题,但这可能有助于澄清你的想法)

你能提供你不理解的评论的英文翻译吗?我说过我是个新手,所以大部分内容我都不理解。到目前为止,你有什么要展示的吗?有一些很好的例子:|正如我所理解的,有些东西可以用代码编写,就像开头和结尾一样关闭另一个视图,因为在这种情况下没有连接到任何视图模型,我是右行的,虽然我并不是建议代码落后是编写UIS的正确方法,但是这确实有效。考虑它应该意味着什么(对你的VM和M)如果您决定使用应用程序并用不同的视图替换整个视图。例如,您希望向导引导新用户完成这些步骤,但高级用户只需要一个对话框。他们应该执行相同的操作,并绑定到相同的ViewModel数据,但外观不同。
<Window x:Class="DialogWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
    WindowStyle="SingleBorderWindow" 
    WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight"
    Style="{DynamicResource {x:Type Window}}">
<ContentPresenter x:Name="DialogPresenter" Content="{Binding .}">

</ContentPresenter>
</Window>

public partial class DialogWindow : Window
{
    public DialogWindow()
    {
        InitializeComponent();
        this.DialogPresenter.DataContextChanged += DialogPresenterDataContextChanged;
    }



    private void DialogPresenterDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var d = e.NewValue as IDialogResultVMHelper;

        if (d == null)
            return;

        d.RequestCloseDialog += new EventHandler<RequestCloseDialogEventArgs>(DialogResultTrueEvent).MakeWeak(eh => d.RequestCloseDialog -= eh);
    }

    private void DialogResultTrueEvent(object sender, RequestCloseDialogEventArgs eventargs)
    {
        this.DialogResult = eventargs.DialogResult;
    }
}

public class RequestCloseDialogEventArgs : EventArgs
{
    public RequestCloseDialogEventArgs(bool dialogresult)
    {
        this.DialogResult = dialogresult;
    }

    public bool DialogResult
    {
        get; set;
    }
}

public interface IDialogResultVMHelper
{
    event EventHandler<RequestCloseDialogEventArgs> RequestCloseDialog;
}