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

}

}

}

相关推荐
❀always❀3 小时前
深入浅出分布式限流(更新中)
分布式·wpf
前端开发与ui设计的老司机3 小时前
从数据洞察到设计变革:UI前端如何利用数字孪生重塑用户体验?
ui·ux
前端开发与ui设计的老司机4 小时前
大数据时代UI前端的智能化升级:基于机器学习的用户意图预测
大数据·ui
前端开发与ui设计的老司机13 小时前
从UI设计到数字孪生实战:构建智慧教育的个性化学习平台
学习·ui
说私域15 小时前
开源链动2+1模式与AI智能名片融合下的S2B2C商城小程序源码:重构大零售时代新生态
人工智能·重构·开源
前端世界15 小时前
鸿蒙UI开发全解:JS与Java双引擎实战指南
javascript·ui·harmonyos
深漂阿碉17 小时前
WPF打包exe应用的图标问题
wpf
三千道应用题17 小时前
WPF学习笔记(26)CommunityToolkit.Mvvm与MaterialDesignThemes
wpf
暮色驶过苍茫20 小时前
软件设计与重构
重构
Deepoch21 小时前
移动机器人的认知进化:Deepoc大模型重构寻迹本质
重构