MVVM(Model-View-ViewModel)是一种软件架构模式,用于实现用户界面(UI)和业务逻辑之间的分离。 view 和 model 之间没有直接的关系,通过 viewModel 来完成数据双向绑定。
xaml界面(输入框与StudentViewModel相关属性绑定)
<Control:MetroWindow.Resources>
<Style x:Key="FromLabel" TargetType="{x:Type Label}">
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="5"></Setter>
</Style>
<Style x:Key="FromTextBox" TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Width" Value="200"></Setter>
</Style>
</Control:MetroWindow.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" DataContext="{Binding StudentViewModel}">
<!--绑定的是MainViewModel中的StudentViewModel属性-->
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource FromLabel}">姓名</Label>
<TextBox Style="{StaticResource FromTextBox}" Text="{Binding Name, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource FromLabel}">班级</Label>
<TextBox Style="{StaticResource FromTextBox}" Text="{Binding ClassName, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Style="{StaticResource FromLabel}">年龄</Label>
<TextBox Style="{StaticResource FromTextBox}" Text="{Binding Age, Mode=TwoWay}"></TextBox>
</StackPanel>
<Button Width="50" HorizontalAlignment="Left" Margin="65,5,5,5" Command="{Binding SaveCommand}">保存</Button>
</StackPanel>
MainWindow.Datacontext为MainViewModel
public partial class MainWindow : MetroWindow
{
MainViewModel vm = new MainViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = this.vm; //MainWindow界面的数据源为MainViewModel
}
}
MainViewModel含有的属性和方法
public class MainViewModel : ObservableObject
{
StudentViewModel studentViewModel;
public StudentViewModel StudentViewModel //MainViewModel实例属性有StudentViewModel
{ get { return studentViewModel; }
set { SetProperty(ref studentViewModel, value, nameof(StudentViewModel)); }
}
public ObservableCollection<Student> Students { get; set; } //用于存储学生对象
public MainViewModel()
{
StudentViewModel = new StudentViewModel(); // 实例化 StudentViewModel 对象
studentViewModel.StudentSaveEvent += StudentViewModel_StudentSaveEvent; // studentViewModel.StudentSaveEvent,处理方法为 StudentViewModel_StudentSaveEvent
Students = new ObservableCollection<Student>(); //实例化-存储学生对象
}
private void StudentViewModel_StudentSaveEvent(object sender, StudentViewModel.StudentSaveEventArgs e)
{
Students.Clear();
foreach (var student in MockData.Students)
{
Students.Add(student);
}
}
StudentViewModel含有的属性和方法
public class StudentViewModel : ObservableObject
{
#region 实例属性:姓名,班级,年龄
string name;
public string Name
{
get { return name; }
set { SetProperty(ref name, value, nameof(Name)); }
}
string classname;
public string ClassName
{
get { return classname; }
set { SetProperty(ref classname, value, nameof(ClassName)); }
}
int age;
public int Age
{
get { return age; }
set { SetProperty(ref age, value, nameof(Age)); }
}
#endregion
public RelayCommand SaveCommand { get; } // 存储命令,用于保存学生信息(只读,防止实例化后被修改)
public StudentViewModel()
{
SaveCommand = new RelayCommand(ExcuteCommand);
}
public event StudentSaveEventHandler StudentSaveEvent; // 学生保存事件
public void ExcuteCommand()
{
Student student;
if((student = MockData.Students.Find(s => s.Name == this.Name)) == null) // 判断是否已存在同名学生对象
{
student = new Student
{
Name = this.Name,
ClassName = this.ClassName,
Age = this.Age,
};
MockData.Students.Add(student);
}
else
{
student.Name = this.Name;
student.ClassName = this.ClassName;
student.Age = this.Age;
}
StudentSaveEvent?.Invoke(this, new StudentSaveEventArgs { Data = student.Name });
}
public class StudentSaveEventArgs
{
public string Data { get; set; }
}
public delegate void StudentSaveEventHandler(object sender, StudentSaveEventArgs e); // 定义用于处理学生保存事件的委托
}
Student类和MockData类
public class Student
{
public string Name { get; set; }
public string ClassName { get; set; }
public int Age { get; set; }
}
public class MockData
{
static List<Student> students = new List<Student>(); // 创建一个静态的 List<Student> 类型的变量
public static List<Student> Students => students; // 创建一个公共的静态只读属性 Students,返回静态变量 students 的值
}