WPF【11_9】WPF实战-重构与美化(UI 与视图模型的联动,实现INotifyPropertyChanged)-示例

--\ViewModels\MainViewModel.cs

public class MainViewModel : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)

{

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

//public List<Customer> Customers { get; set; } = new();

public ObservableCollection<CustomerViewModel> Customers { get; set; } = new();

public ObservableCollection<AppointmentViewModel> Appointments { get; set; } = new();

private CustomerViewModel _selectedCustomer;

public CustomerViewModel SelectedCustomer

{

get => _selectedCustomer;

set

{

if (value != _selectedCustomer)

{

_selectedCustomer = value;

RaisePropertyChanged(nameof(SelectedCustomer));

LoadAppointments(SelectedCustomer.Id);

}

}

}

public void LoadCustomers()

{

Customers.Clear();

using (var db = new AppDbContext())

{

// Select * from Customers as c join Appointments as a on c.Id = a. CustomerId

var customers = db.Customers

//.Include(c => c.Appointments)

.ToList();

foreach (var c in customers)

{

Customers.Add(new CustomerViewModel(c));

}

}

}

public void ClearSelectedCustomer()

{

_selectedCustomer = null;

RaisePropertyChanged(nameof(SelectedCustomer));

}

public void SaveCustomer(string name, string idNumber, string address)

{

if(SelectedCustomer != null)

{

// 更新客户数据

using (var db = new AppDbContext())

{

var customer = db.Customers.Where(c => c.Id == SelectedCustomer.Id).FirstOrDefault();

customer.Name = name;

customer.IdNnumber = idNumber;

customer.Address = address;

db.SaveChanges();

}

}

else

{

// 添加新客户

using (var db = new AppDbContext())

{

var newCustomer = new Customer()

{

Name = name,

IdNnumber = idNumber,

Address = address

};

db.Customers.Add(newCustomer);

db.SaveChanges();

}

LoadCustomers();

}

}

public void LoadAppointments(int customerId)

{

Appointments.Clear();

using (var db = new AppDbContext())

{

var appointments = db.Appointments.Where(a => a.CustomerId == customerId).ToList();

foreach(var a in appointments)

{

Appointments.Add(new AppointmentViewModel(a));

}

}

}

public void AddAppointment(DateTime selectedDate)

{

if (SelectedCustomer == null)

{

return;

}

using (var db = new AppDbContext())

{

var newAppointment = new Appointment()

{

Time = selectedDate,

CustomerId = SelectedCustomer.Id

};

db.Appointments.Add(newAppointment);

db.SaveChanges();

}

LoadAppointments(SelectedCustomer.Id);

}

}

--\ViewModels\CustomerViewModel.cs

public class CustomerViewModel

{

private Customer _customer;

public CustomerViewModel(Customer customer)

{

_customer = customer;

}

public int Id { get => _customer.Id; }

public string Name

{

get => _customer.Name; set

{

if (_customer.Name != value)

{

_customer.Name = value;

}

}

}

public string IdNnumber

{

get => _customer.IdNnumber; set

{

if (_customer.IdNnumber != value)

{

_customer.IdNnumber = value;

}

}

}

public string Address

{

get => _customer.Address; set

{

if (_customer.Address != value)

{

_customer.Address = value;

}

}

}

}

--\ViewModels\AppointmentViewModel.cs

public class AppointmentViewModel

{

private Appointment _appointment;

public AppointmentViewModel(Appointment appointment)

{

_appointment = appointment;

}

public int Id { get => _appointment.Id; }

public DateTime Time

{

get => _appointment.Time;

set

{

if (value != _appointment.Time)

{

_appointment.Time = value;

}

}

}

}

--\WPF_CMS\MainWindow.xaml

<Window x:Class="WPF_CMS.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:WPF_CMS"

xmlns:controls="clr-namespace:WPF_CMS.Controls"

mc:Ignorable="d"

Title="MainWindow" Height="450" Width="800">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition />

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="240"/>

<ColumnDefinition Width="280"/>

<ColumnDefinition />

</Grid.ColumnDefinitions>

<!--header-->

<controls:HeaderControl Grid.ColumnSpan="3"/>

<StackPanel Grid.Row="1" Grid.Column="0">

<Button Content="添加客户" Click="ClearSelectedCustomer_Click"/>

<ListView ItemsSource="{Binding Customers, Mode=OneWay}" DisplayMemberPath="Name" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" />

</StackPanel>

<StackPanel Grid.Row="1" Grid.Column="1">

<TextBlock Text="姓名" Margin="10 10 10 0"/>

<TextBox Name="NameTextBox" Margin="10" Text="{Binding SelectedCustomer.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

<TextBlock Text="身份证" Margin="10 10 10 0"/>

<TextBox Name="IdTextBox" Margin="10" Text="{Binding SelectedCustomer.IdNnumber, Mode=TwoWay}" />

<TextBlock Text="地址" Margin="10 10 10 0"/>

<TextBox Name="AddressTextBox" Margin="10" Text="{Binding SelectedCustomer.Address, Mode=TwoWay}" />

<Button Content="保存" Margin="10 10 10 30" VerticalAlignment="Bottom" HorizontalAlignment="Left" Click="SaveCustomer_Click" />

</StackPanel>

<StackPanel Grid.Row="1" Grid.Column="2">

<ListView ItemsSource="{Binding Appointments, Mode=TwoWay}" DisplayMemberPath="Time"/>

<TextBlock Text="添加新预约" />

<DatePicker Name="AppointmentDatePicker" Margin="10" />

<Button Content="预约" Click="AddAppointment_Click" />

</StackPanel>

</Grid>

</Window>

--\WPF_CMS\MainWindow.xaml.cs

public partial class MainWindow : Window

{

private MainViewModel _viewModel;

public MainWindow()

{

InitializeComponent();

_viewModel = new MainViewModel();

_viewModel.LoadCustomers();

DataContext = _viewModel;

//ShowCustomers();

}

private void ClearSelectedCustomer_Click(object sender, RoutedEventArgs e)

{

_viewModel.ClearSelectedCustomer();

}

private void SaveCustomer_Click(object sender, RoutedEventArgs e)

{

try

{

string name = NameTextBox.Text.Trim();

string idNumber = IdTextBox.Text.Trim();

string address = AddressTextBox.Text.Trim();

_viewModel.SaveCustomer(name, idNumber, address);

}

catch (Exception error)

{

MessageBox.Show(error.ToString());

}

}

private void AddAppointment_Click(object sender, RoutedEventArgs e)

{

try

{

DateTime time = DateTime.Parse(AppointmentDatePicker.Text);

_viewModel.AddAppointment(time);

}

catch (Exception error)

{

MessageBox.Show(error.ToString());

}

}

}

相关推荐
riveting4 小时前
68元开发板,开启智能硬件新篇章——明远智睿SSD2351深度解析
linux·图像处理·人工智能·重构·智能硬件
枣树一4 小时前
2025.5.22 Axure 基础与线框图制作学习笔记
ui·axure
军训猫猫头4 小时前
95.WPF中图片控件的使用与资源路径设置 WPF例子 C#例子
ui·c#·.net·wpf
qq_340474024 小时前
5 WPF中的Page页面的使用
开发语言·c#·wpf
SoFlu软件机器人7 小时前
重构开发范式!飞算JavaAI革新Spring Cloud分布式系统开发
spring·spring cloud·重构
唯创知音7 小时前
唯创WT2606B TFT显示灵动方案,重构电子锁人机互动界面,赋能智能门锁全场景交互!
重构·交互
向宇it9 小时前
【unity游戏开发——编辑器扩展】EditorUtility编辑器工具类实现如文件操作、进度条、弹窗等操作
ui·unity·c#·编辑器·游戏引擎
benben04413 小时前
Unity3D仿星露谷物语开发54之退出菜单及创建可执行文件
游戏·ui·unity·游戏引擎
keke1014 小时前
WPF【11_3】WPF实战-重构与美化(可复用的UI组件)
ui·重构·wpf
TwilightLemon18 小时前
WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
wpf