翻譯|產(chǎn)品更新|編輯:龔雪|2022-07-25 11:06:11.060|閱讀 159 次
概述:本文主要介紹如何在WinUI中創(chuàng)建第一個(gè)MVVM應(yīng)用程序。歡迎下載相關(guān)工具體驗(yàn)~
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
在本文中,我們將描述如何從頭開始創(chuàng)建WinUI MVVM 應(yīng)用程序,并在此過程中展示DevExpress WinUI MVVM框架的強(qiáng)大功能。
最初,官方技術(shù)團(tuán)隊(duì)為WPF平臺創(chuàng)建了MVVM 框架,后來發(fā)現(xiàn)在這個(gè)框架中開發(fā)的技術(shù)可以很容易地在 WinForms 中使用,所以將框架移植到那里。 在 v22.1 中,官方團(tuán)隊(duì)針對WinUI優(yōu)化了MVVM框架,保持核心功能不變,如果您使用我們的WPF或WinForms控件,在遷移到WinUI時(shí)不會遇到任何問題。
讓我們從創(chuàng)建裸視圖模型開始,您可以選擇以下視圖模型類型:
本文中使用第一個(gè)選項(xiàng),因?yàn)樗梢宰屇囊晥D模型代碼保持干凈、緊湊,并幫助避免拼寫錯(cuò)誤。
將DevExpress.Mvvm.CodeGenerators和DevExpress.WinUI NuGet包添加到您的項(xiàng)目中,添加包后創(chuàng)建一個(gè)視圖模型類并將GenerateViewModel屬性分配給它:
using DevExpress.Mvvm.CodeGenerators; [GenerateViewModel] public partial class MainViewModel { [GenerateProperty] string userName; [GenerateCommand] void Register() { Debug.WriteLine($"{UserName} was successfully registered!"); } }
請注意,您需要將類設(shè)為部分并添加 DevExpress.Mvvm.CodeGenerators 命名空間。
編譯時(shí)生成器會自動(dòng)創(chuàng)建具有 INotifyPropertyChanged 支持的視圖模型對應(yīng)項(xiàng):
partial class MainViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; protected void RaisePropertyChanged(PropertyChangedEventArgs e) => PropertyChanged?.Invoke(this, e); public string? UserName { get => userName; set { if(EqualityComparer.Default.Equals(userName, value)) return; userName = value; RaisePropertyChanged(UserNameChangedEventArgs); } } DelegateCommand? registerCommand; public DelegateCommand RegisterCommand => registerCommand ??= new DelegateCommand(Register, null); static PropertyChangedEventArgs UserNameChangedEventArgs = new PropertyChangedEventArgs(nameof(UserName)); }
您可以在項(xiàng)目中查看生成的類:Dependencies -> Analyzers -> DevExpress.Mvvm.CodeGenerators -> DevExpress.Mvvm.CodeGenerators.ViewModelGenerator -> MainViewModel.g.cs
將 CanRegister 方法添加到您的視圖模型以確定何時(shí)可以執(zhí)行 Register 命令。 請注意,WinUI 命令不使用 CommandManager,因此您需要使用 RaiseCanExecuteChanged 手動(dòng)刷新 CanExecute 狀態(tài):
public partial class MainViewModel { //... void OnUserNameChanged() { RegisterCommand.RaiseCanExecuteChanged(); } bool CanRegister() => !string.IsNullOrEmpty(UserName); }
代碼生成器將自動(dòng)將 OnUserNameChanged 和 CanRegister 合并到 UserName 屬性和 Register 命令中。
視圖模型具有存儲用戶名的UserName屬性和注冊用戶的RegisterCommand方法,創(chuàng)建一個(gè)簡單的UI 來使用視圖模型,向主窗口添加一個(gè) TextBox 和一個(gè) Button 并將它們綁定到視圖模型的屬性和命令:
<StackPanel> <TextBox Text="{x:Bind ViewModel.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <Button Content="Register" Command="{x:Bind ViewModel.RegisterCommand}"/> </StackPanel>
您可能已經(jīng)注意到,本文中使用了 替代 Binding,x:Bind 是 UWP 中引入的一個(gè)相對較新的標(biāo)記擴(kuò)展。它在編譯時(shí)使用類型信息來優(yōu)化綁定,因此最好盡可能使用它。 在窗口或用戶控件中使用 x:Bind 時(shí),默認(rèn)綁定源是窗口本身,因此需要將視圖模型定義為窗口屬性:
public sealed partial class MainWindow : Window { public MainViewModel ViewModel { get; } = new MainViewModel(); public MainWindow() { this.InitializeComponent(); } }
現(xiàn)在簡單的 MVVM 應(yīng)用程序可以將信息從視圖發(fā)送到視圖模型并執(zhí)行視圖模型的命令,擴(kuò)展它以在用戶單擊Register按鈕時(shí)顯示一個(gè)消息框。使用 UI 服務(wù),可以不直接從視圖模型訪問視覺元素,這將幫助我們保持干凈的 MVVM 模式。將 MessageBoxService 添加到視圖并將其 ServiceClient 屬性綁定到您的視圖模型:
<Window ... xmlns:dxc="using:DevExpress.WinUI.Core"> <StackPanel> <dxc:Interaction.Behaviors> <dxc:MessageBoxService ServiceClient="{x:Bind ViewModel}"/> </dxc:Interaction.Behaviors> <TextBox Text="{x:Bind ViewModel.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <Button Content="Register" Command="{x:Bind ViewModel.RegisterCommand}"/> </StackPanel> </Window>
然后,將 ImplementISupportUIServices 參數(shù)添加到 GenerateViewModel 屬性并在 Register 方法中使用 MessageBoxService:
using DevExpress.Mvvm; using DevExpress.Mvvm.CodeGenerators; [GenerateViewModel(ImplementISupportUIServices = true)] public partial class MainViewModel { [GenerateProperty] string userName; IMessageBoxService MessageBoxService { get => ServiceContainer.GetService<IMessageBoxService>(); } [GenerateCommand] void Register() { MessageBoxService.ShowAsync($"{UserName} was successfully registered!", "Registration"); } }
現(xiàn)在,用戶單擊按鈕后將看到一個(gè)消息框。 請注意,您的視圖模型不會直接訪問任何視覺元素,相反服務(wù)機(jī)制被用作中間層。
讓我們通過在用戶按下 Enter 鍵時(shí)調(diào)用 Register 命令來增強(qiáng)用戶體驗(yàn),WinUI 按鈕沒有 IsDefault 屬性,因此需要處理按鍵事件以捕捉按下 Enter 的時(shí)刻。但MVVM 套件具有 KeyToCommand 行為,可以在使用指定鍵時(shí)調(diào)用命令。 將 KeyToCommand 行為添加到 Interaction.Behaviors 集合并設(shè)置其 KeyGesture 和 Command 屬性:
<StackPanel> <dxc:Interaction.Behaviors> <dxc:KeyToCommand KeyGesture="Enter" Command="{x:Bind ViewModel.RegisterCommand}"/> <!--...--> </dxc:Interaction.Behaviors> <!--...--> </StackPanel>
KeyToCommand 是一種可以立即使用的操作,但是您可以輕松地根據(jù)需要?jiǎng)?chuàng)建自定義行為,以避免在不同的視圖中編寫類似的代碼隱藏。
DevExpress WPF擁有120+個(gè)控件和庫,將幫助您交付滿足甚至超出企業(yè)需求的高性能業(yè)務(wù)應(yīng)用程序。通過DevExpress WPF能創(chuàng)建有著強(qiáng)大互動(dòng)功能的XAML基礎(chǔ)應(yīng)用程序,這些應(yīng)用程序?qū)W⒂诋?dāng)代客戶的需求和構(gòu)建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件的衍伸產(chǎn)品,還是以數(shù)據(jù)為中心的商業(yè)智能產(chǎn)品,都能通過DevExpress WPF控件來實(shí)現(xiàn)。
DevExpress技術(shù)交流群6:600715373 歡迎一起進(jìn)群討論
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:慧都網(wǎng)