簡體   English   中英

這是使用MVVM設計模式創建新窗口的最佳方法

[英]Which is the best way for creating new windows using the MVVM design pattern

我想問問哪種是使用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
}

為了完整性:

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

首先是一個問題,另一個是違反直覺的問題。 打開新窗口動作與MVVM有什么關系?

我個人認為根本沒有任何聯系。 實際上,就像其他幾個UI構造一樣,它完全在View層中發生。 還有其他一些類似的概念,

  • 基於導航的界面(使用NavigationWindow),其中將數據填充到表單中, NextNext )以切換到下一頁
  • 打開上下文菜單,其中包含一組可變的操作
  • 一個選項卡式控件,可動態加載活動頁面

所有這些都是向用戶顯示新視圖的不同方式。 僅通過顯示綁定到ViewModel的新UI元素,所有這些元素都存在於View層中。

但是...圍繞MVVM發展了很多模式來支持這一點。 通常,這是使用服務或控制器來處理視圖操作,請檢查所選的MVVM庫是否支持顯示新視圖的方法。

最后,讓我感到困惑的一件事是,當您需要執行操作並更改視圖時發生了什么。 通常,您會將UI對象(例如按鈕)綁定到ViewModel級別的命令以執行操作,然后依靠綁定來更新顯示新值的UI控件。 由於ViewModel不應該了解View,因此任何更改UI的操作都只能在View中進行。 這意味着您無法綁定到ViewModel命令。 幸運的是,您可以在視圖級別創建一個命令,該命令委派給視圖模型級別的操作並更改UI。

(嗯...回讀,不確定是否能回答問題,但這可能有助於闡明您的想法)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM