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

}

}

}

相关推荐
云雾J视界5 小时前
AI时代技术面试重构:谷歌如何用Vibe Coding与抗作弊革命重塑招聘
人工智能·google·面试·重构·谷歌·ai工具·技术面试
深蓝学院5 小时前
智源研究院新研究:突破物理世界智能边界的RoboBrain 2.0,将重构具身AI能力天花板
人工智能·重构
顾道长生'5 小时前
(Arxiv-2025)重构对齐提升了统一多模态模型的性能
重构
伊莲娜生活5 小时前
大健康时代下的平台电商:VTN平台以科研创新重构健康美丽消费生态
人工智能·物联网·重构
健康有益科技5 小时前
大模型食材识别技术革新:AI重构精准营养管理
大数据·人工智能·计算机视觉·重构
拾忆,想起9 小时前
Redisson 分布式锁的实现原理
java·开发语言·分布式·后端·性能优化·wpf
weixin_4640780711 小时前
wpf依赖注入驱动的 MVVM实现(含免费源代码demo)
wpf
yuanpan13 小时前
认识跨平台UI框架Flutter和MAUI区别,如何选。
flutter·ui·maui
beyond谚语15 小时前
一、WPF入门介绍+Grid和StackPanel布局介绍+实战模拟Notepad++页面布局
wpf
CPU不够了15 小时前
WPF常见问题清单
wpf·自适应