簡體   English   中英

在WPF中使用MVVM模式創建對話框時,如何實例化對話框並記錄用戶輸入

[英]How to instantiate a dialog and record user input while MVVM pattern is used to create dialog in WPF

我是C ++開發人員,並且是WPF和MVVM的新手。 如果我選擇了錯誤的單詞問我的問題,請忍受我

我在MFC / C ++中有我的Main應用程序,該應用程序將一些數據傳遞給C#庫( CLI被用作中間層)。 C#庫中 ,有一段代碼可以打開對話框,填充數據,並通過以下方式將用戶選擇通知給調用對象:

public classA()
{
    MyDialog dlg = new MyDialog(param1, param2, param3)
    if(dlg.ShowDialog().GetValueOrDefault())
    {
        var name = dlg.name;
        var roll = dlg.roll;
    }
    else
    {
        var name = string.Empty;
        var roll = string.Empty;
    }
}

現在,Dialog已被修改並使用MVVM模式實現。

我已將以下文件創建為實施的一部分-1

  1. MyDialogView.Xaml
  2. MyDialogView.xaml.cs
  3. MyDialogViewModel.cs
  4. MyDialogModel.cs

我的問題是,現在如何從我的classA實例化新對話框,以便使用傳遞給對話框的參數以與以前相同的方式填充數據,並記錄用戶選擇,而不會丟失任何數據並安全地關閉視圖。

標准MVVM方法的工作方式如下(至少在使用MVVM Light時):

  1. 您有一個VM層,一個類庫。
  2. 您有一個View層,一個WPF控件庫或WPF應用程序。
  3. 視圖層添加了對VM層的引用。 VM層對View一無所知。
  4. 您為對話框的VM創建一個普通的公共類。 稱之為DialogVM或其他名稱。 確保此類繼承自MVVM Light的內置ViewModelBase 這將使您能夠訪問MVVM Light提供的更改通知方法。 在您的情況下,可能看起來像這樣:

     public partial class DialogVM : ViewModelBase { private string _Name; public string Name { get { return _Name; } set { Set(ref _Name, value); } } private string _Roll; public string Roll { get { return _Roll; } set { Set(ref _Roll, value); } } } 
  5. VM層具有一個稱為ViewModelLocator的全局靜態類。 此類執行IoC / DI,並提供公共靜態屬性以公開不同的VM。 (在您的情況下,對話框的VM轉到VM項目,並且ViewModelLocator看起來像這樣:

     using System; namespace VMLayer { public class ViewModelLocator { static ViewModelLocator() { SimpleIoc.Default.Register<DialogVM>(true); } public static DialogVM MyDialog => SimpleIoc.Default.GetInstance<DialogVM>(); } } 
  6. 您的對話框( Window )轉到“視圖”層,並使用此公開的屬性MyDialog為對話框提供DataContext

     <Window x:Class="GlasshouseTestingShell.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:vm="clr-namespace:VMLayer;assembly=VMLayer" DataContext="{x:Static vm:ViewModelLocator.MyDialog}" d:DataContext="{d:DesignInstance Type=vm:DialogVM}"> </Window> 
  7. 看看我們如何干凈地創建View層的DataContext而不在View層中編寫C#代碼行。 Binding表達式和其他地方都獲得了所有設計時Intellisense的意義上,這也很優雅。
  8. 現在,您將所有UI內容(文本框,按鈕等)綁定到對話框VM公開的公共屬性和命令。 后面的代碼中仍然沒有一行。 在您的情況下,可能看起來像這樣:

     <TextBox Text="{Binding Name}" /> 

其余的東西在C ++中:

  1. 您可以在C ++項目中添加對View和VM DLL的引用。
  2. 創建對話框的對象。 它將自動實例化其VM並執行綁定。 您調用ShowDialog()使其顯示在屏幕上。
  3. 使用在對話框中執行操作,最后按確定或取消。
  4. 您捕獲對話框結果,然后訪問對話框對象的DataContext屬性,該屬性是DialogVM類的對象。 您可以從中訪問用戶提供的值,因為綁定已在VM中為您更新了這些屬性。

我不確定我是否會遵循您的所有要求,但這大致就是我將要完成的任務的方式:

實例化類A中的視圖和視圖模型。

在視圖模型上設置所需的任何參數。 作為屬性或通過構造函數注入。

將視圖的datacontext設置為viewmodel。

然后,您需要綁定的所有內容都應在它們之間進行綁定。

showdialog視圖。

用戶在視圖中進行編輯,更改將保留在viewmodel屬性中。

他們完成了編輯,然后您可以使用viewmodel屬性。 也許其中之一就是您提到的模型。 也許是由視圖模型實例化模型以獲取數據,或者如果更方便,則由classA實例化。 在后一種情況下,您可能必須將該模型傳遞給viewmodel。

牢記以上內容。

一些粗略的代碼:

public class ClassA
{
    MyDialogViewModel vm = new MyDialogViewModel { Name = "X", Roll = "Y" };
    MyDialog dlg = new MyDialog();
    dlg.ShowDialog();
    var name = vm.Name;
    var roll = vm.roll;

    // Do something to persist your data as necessary. Either here or in a model within the viewmodel
}

名稱和滾動可能綁定到視圖中的某些文本框或某些文本屬性。

如果只是簡單地獲得兩個字符串值,那么我認為實際上擁有一個模型根本沒有任何好處。 另一方面,如果更多地涉及處理,那么視圖模型當然可以實例化模型。

MyDialogViewModel應該實現inotifypropertychanged,並且您需要綁定的任何東西都應該是公共屬性。 不知道您是否需要屬性更改通知,但始終執行它。 (可選)提高從屬性設置器更改的屬性。

暫無
暫無

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

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