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());

}

}

}

相关推荐
老蒋新思维2 小时前
创客匠人峰会深度解析:知识变现的 “信任 - 效率” 双闭环 —— 从 “单次交易” 到 “终身复购” 的增长密码
大数据·网络·人工智能·tcp/ip·重构·数据挖掘·创客匠人
狮恒3 小时前
OpenHarmony Flutter 分布式数据管理:跨设备数据同步与一致性保障方案
分布式·flutter·wpf·openharmony
小小测试开发3 小时前
提升App UI自动化性能与效率:从脚本到架构的全链路优化指南
ui·架构·自动化
BW.SU6 小时前
RUI Builder 图形化UI设计工具
ui·hmi·ui设计·ra8889·ra6809·rui·人机界面
Macbethad6 小时前
工业设备IO模拟程序
wpf
老蒋新思维7 小时前
创客匠人峰会新解:AI 时代知识变现的 “信任分层” 法则 —— 从流量到高客单的进阶密码
大数据·网络·人工智能·tcp/ip·重构·创始人ip·创客匠人
惟恋惜10 小时前
Jetpack Compose 界面元素状态(UI Element State)详解
android·ui·android jetpack
狮恒10 小时前
OpenHarmony Flutter 分布式设备发现与连接:无感组网与设备协同管理方案
分布式·flutter·wpf·openharmony
云和数据.ChenGuang10 小时前
鸿蒙负一屏的技术定位与核心价值
华为·wpf·harmonyos
_李小白10 小时前
【Android FrameWork】延伸阅读:IGraphicBufferProducer驱动UI绘制过程
android·ui