我开发了一个 WPF 应用程序,它由一个主窗口和两个用户控件组成。第一个用户控件包含一个按钮,第二个用户控件有一个文本框。主窗口包含一个 DataGrid。
我需要进行设置,以便当我在第二个用户控件的文本框中输入一个值,然后单击第一个用户控件中的按钮时,文本框中的值将添加到主窗口中的 DataGrid 中。
我怎样才能实现这个目标?
第一个用户控制:
<UserControl ....>
<Grid>
<Button x:Name="btnAddDetails" Content="Add details" Width="170" Height="60" Click="btnAddDetails_Click"/>
</Grid>
</UserControl>
第二个用户控制:
<UserControl ....>
<StackPanel>
<TextBox x:Name="txtName"/>
<TextBox x:Name="txtDesc"/>
<CheckBox x:Name="chkIsActive" Content="IsActive"/>
</StackPanel>
</UserControl>
在WPF中开发应用程序有两种方式:代码隐藏模式和MVVM(Model,View,ViewModel),其中MVVM是推荐的方式。
我将引导您逐步轻松地使用 MVVM 模式创建您想要的内容(推荐方式):
2-创建用户模型:
3-创建 RelayCommand 类来处理添加用户按钮点击:
4-添加MainVM:
5-现在在 MainWindow xaml 文件中添加这两个命名空间:
注意:您会看到我在 ViewModels 文件夹中添加了 ViewModel,并且为用户控件添加了相同的内容,尽管它是一个我仅用来组织文件的简单应用程序。
5.1-然后使用创建的用户控件(在同一个 xaml 文件中):
注意:示例在编写之前已经过测试,您可以在这里找到它:https://github.com/amuza2/100DaysOfCode/tree/main/Day93/WpfApp1/SimpleWpfApp
解释一些关键思想:
1- View(用户控件)和 ViewModel(MainVM)之间的数据绑定,就像在 FillUserDataUserControl 中一样,这会在文本框的 Text 属性和ViewModel(MainVM)中的属性
Text = "{Binding CurrentUser.Name}"
之间创建绑定。CurrentUser.Name
2- INotifyPropertyChanged:User 模型和 MainViewModel 都实现了此接口,这对于双向绑定至关重要。当属性发生变化时,
PropertyChanged
会通过该方法引发事件OnPropertyChanged()
,提醒 UI 进行更新。3- DataContext:在 MainWindow.xaml 中,该行将
<Window.DataContext><viewmodels:MainVM /></Window.DataContext>
ViewModel 设置为窗口及其子控件中所有绑定的数据源。此绑定系统允许 UI 中的更改更新 ViewModel(反之亦然),而无需编写显式事件处理程序和 UI 更新代码。
4- 在 ButtonUserControl.xaml 中,
Command="{Binding AddUserCommand}"
将按钮的 Command 属性绑定到 ViewModel(MainVM)中的 AddUserCommand 属性。RelayCommand
实现ICommand
接口,该接口定义 WPF 中的命令契约。RelayCommand 中的 Commandmanager 连接到 WPF 的 CommandManager,当输入状态改变时(例如在名称文本框中输入文本时),它会自动调用 CanExecute。
5- 与常规不同
List<T>
,ObservableCollection 实现了INotifyCollectionChanged
,它在添加、删除项目或集合发生变化时会引发事件,这意味着当您Users.Add(newUser)
在 ViewModel 中调用时,ObservableCollection 会自动引发 CollectionChanged 事件,DataGrid 会监听该事件,这意味着 DataGrid 会再次自动更新以显示新项目而无需任何手动刷新代码🥳。如果我们使用常规列表,添加项目不会自动更新 UI。
您可能会说,对于一个只有少量控件的简单应用程序来说,这已经够多了,您是对的,但是当您构建中型到大型项目时,MVVM 就会大放异彩。