wpf mvvm框架搭建 使用自定义控件工程事例
时间: 2023-08-06 13:07:52 浏览: 291
WPF自定义控件开发Sample
5星 · 资源好评率100%
好的,下面是一个 WPF MVVM 框架搭建并使用自定义控件的工程事例:
1. 创建一个 WPF 应用程序项目。
2. 在项目中添加一个名为 Models 的文件夹,并在其中添加一个名为 Student.cs 的类,该类包含学生的姓名和年龄属性:
```csharp
namespace WpfMvvmDemo.Models
{
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
}
```
3. 在项目中添加一个名为 ViewModels 的文件夹,并在其中添加一个名为 MainViewModel.cs 的类,该类包含一个名为 Students 的可观察集合属性,用于存储学生对象,并在构造函数中初始化该集合:
```csharp
using System.Collections.ObjectModel;
using WpfMvvmDemo.Models;
namespace WpfMvvmDemo.ViewModels
{
public class MainViewModel
{
public ObservableCollection<Student> Students { get; set; }
public MainViewModel()
{
Students = new ObservableCollection<Student>
{
new Student { Name = "张三", Age = 18 },
new Student { Name = "李四", Age = 19 },
new Student { Name = "王五", Age = 20 }
};
}
}
}
```
4. 在项目中添加一个名为 Controls 的文件夹,并在其中添加一个名为 StudentControl.xaml 的自定义控件。该控件包含一个 TextBlock 控件和一个 Button 控件,用于显示学生的姓名和年龄,并提供一个名为 DeleteCommand 的依赖属性,以便在删除按钮被点击时执行删除操作:
```xaml
<UserControl x:Class="WpfMvvmDemo.Controls.StudentControl"
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"
xmlns:local="clr-namespace:WpfMvvmDemo.Controls"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="200">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Margin="5" />
<Button Grid.Column="1" Content="删除" Margin="5" Command="{Binding DeleteCommand}" />
</Grid>
</UserControl>
```
5. 在 StudentControl.xaml.cs 中,定义 DeleteCommand 依赖属性,并在构造函数中为该属性设置默认值:
```csharp
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfMvvmDemo.Controls
{
public partial class StudentControl : UserControl
{
public static readonly DependencyProperty DeleteCommandProperty =
DependencyProperty.Register("DeleteCommand", typeof(ICommand), typeof(StudentControl), new PropertyMetadata(null));
public ICommand DeleteCommand
{
get { return (ICommand)GetValue(DeleteCommandProperty); }
set { SetValue(DeleteCommandProperty, value); }
}
public StudentControl()
{
InitializeComponent();
DeleteCommand = new RelayCommand(Delete);
}
private void Delete(object parameter)
{
// 执行删除操作
}
}
}
```
6. 在项目中添加一个名为 Commands 的文件夹,并在其中添加一个名为 RelayCommand.cs 的类,该类实现了 ICommand 接口,用于在控件中执行命令:
```csharp
using System;
using System.Windows.Input;
namespace WpfMvvmDemo.Commands
{
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute?.Invoke(parameter) ?? true;
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
```
7. 在项目中添加一个名为 Converters 的文件夹,并在其中添加一个名为 AgeToStringConverter.cs 的类,该类实现了 IValueConverter 接口,用于将学生的年龄转换为字符串:
```csharp
using System;
using System.Globalization;
using System.Windows.Data;
namespace WpfMvvmDemo.Converters
{
public class AgeToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int age)
{
return $"{age} 岁";
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
```
8. 在 MainWindow.xaml 中,使用 StudentControl 自定义控件,将 ItemsControl 控件绑定到 MainViewModel 中的 Students 属性,并使用 AgeToStringConverter 将学生的年龄转换为字符串:
```xaml
<Window x:Class="WpfMvvmDemo.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfMvvmDemo.Views"
xmlns:viewModel="clr-namespace:WpfMvvmDemo.ViewModels"
xmlns:controls="clr-namespace:WpfMvvmDemo.Controls"
xmlns:converters="clr-namespace:WpfMvvmDemo.Converters"
xmlns:commands="clr-namespace:WpfMvvmDemo.Commands"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<viewModel:MainViewModel />
</Window.DataContext>
<Window.Resources>
<converters:AgeToStringConverter x:Key="AgeToStringConverter" />
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:StudentControl>
<controls:StudentControl.DataContext>
<viewModel:StudentViewModel Name="{Binding Name}" Age="{Binding Age}" DeleteCommand="{Binding DataContext.DeleteStudentCommand, RelativeSource={RelativeSource AncestorType=Window}}" />
</controls:StudentControl.DataContext>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="5" />
<TextBlock Text="{Binding Age, Converter={StaticResource AgeToStringConverter}}" Margin="5" />
</StackPanel>
</controls:StudentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
```
9. 在项目中添加一个名为 StudentViewModel.cs 的类,该类用于将学生对象转换为可供 StudentControl 使用的视图模型,并包含一个名为 DeleteCommand 的命令,用于删除该学生:
```csharp
using System.Windows.Input;
using WpfMvvmDemo.Commands;
namespace WpfMvvmDemo.ViewModels
{
public class StudentViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public ICommand DeleteCommand { get; set; }
public StudentViewModel(string name, int age, ICommand deleteCommand)
{
Name = name;
Age = age;
DeleteCommand = deleteCommand;
}
}
}
```
10. 在 MainViewModel.cs 中,添加一个名为 DeleteStudentCommand 的命令,用于删除选定的学生:
```csharp
using System.Collections.ObjectModel;
using System.Windows.Input;
using WpfMvvmDemo.Commands;
using WpfMvvmDemo.Models;
namespace WpfMvvmDemo.ViewModels
{
public class MainViewModel
{
public ObservableCollection<Student> Students { get; set; }
public ICommand DeleteStudentCommand { get; set; }
public MainViewModel()
{
Students = new ObservableCollection<Student>
{
new Student { Name = "张三", Age = 18 },
new Student { Name = "李四", Age = 19 },
new Student { Name = "王五", Age = 20 }
};
DeleteStudentCommand = new RelayCommand(DeleteStudent);
}
private void DeleteStudent(object parameter)
{
if (parameter is Student student)
{
Students.Remove(student);
}
}
}
}
```
这就是一个 WPF MVVM 框架搭建并使用自定义控件的工程事例。通过这个例子,你可以学习到如何使用自定义控件和视图模型,实现更加灵活的界面设计和命令操作。
阅读全文