如何不使用MVVM在WPF的DataGrid中显示用户输入并解决弹窗关闭问题
问题1:提交后弹出新主窗口、历史数据不保留的解决
你原有代码的核心问题是提交时每次都新建MainWindow实例,导致原窗口的历史数据无法保留。无需MVVM的前提下最简单的实现方式是把AddDetails作为模态对话框弹出,提交后直接把数据返回给已存在的主窗口实例即可。
修正后的完整代码
1. MainWindow.xaml (修正绑定路径错误)
<Window x:Class="WPF_Practice.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_Practice" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <DataGrid x:Name="DataGrid1" ColumnWidth="200" HorizontalAlignment="Left" Height="244" Margin="117, 65, 0,0" VerticalAlignment="Top" Width="522" IsReadOnly="True"> <DataGrid.Columns> <DataGridTextColumn Header="姓名" Binding="{Binding name}" Width="130"/> <DataGridTextColumn Header="年龄" Binding="{Binding age}" Width="130"/> <DataGridTextColumn Header="城市" Binding="{Binding city}" Width="*"/> </DataGrid.Columns> </DataGrid> <Button x:Name="ADD" Click="ADD_Click" Content="新增" HorizontalAlignment="left" VerticalAlignment="Top" Margin="127,335,0,0" Width="74"/> </Grid> </Window>
2. MainWindow.xaml.cs
using System.Windows; namespace WPF_Practice { // 将PersonalInfo移到公共命名空间,方便两端访问 public class PersonalInfo { public string name { get; set; } public int age { get; set; } public string city { get; set; } } public partial class MainWindow : Window { public MainWindow() { // 补全无参构造的界面初始化逻辑 InitializeComponent(); } private void ADD_Click(object sender, RoutedEventArgs e) { AddDetails addDetails = new AddDetails(); // 弹出模态窗口等待提交结果 if (addDetails.ShowDialog() == true) { // 直接将返回的信息追加到当前主窗口的DataGrid DataGrid1.Items.Add(addDetails.SubmitInfo); } } } }
3. AddDetails.xaml.cs
using System.Windows; namespace WPF_Practice { public partial class AddDetails : Window { // 对外暴露提交的信息,供主窗口读取 public PersonalInfo SubmitInfo { get; private set; } public AddDetails() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { // 先做字段非空校验 if (string.IsNullOrWhiteSpace(Name.Text) || string.IsNullOrWhiteSpace(Age.Text) || string.IsNullOrWhiteSpace(City.Text)) { MessageBox.Show("请填写全部字段信息"); // 校验不通过直接返回,不关闭窗口 return; } // 校验年龄格式合法性 if (!int.TryParse(Age.Text, out int age)) { MessageBox.Show("年龄请填写合法数字"); return; } // 校验全部通过后构造数据对象 SubmitInfo = new PersonalInfo() { name = Name.Text, age = age, city = City.Text }; // 只有设置DialogResult为true时,窗口才会关闭并返回确认状态 this.DialogResult = true; } } }
问题2:对话框校验不通过自动关闭的解决
你原有对话框逻辑的错误是校验时机不对:在主窗口判断ShowDialog()==true时对话框已经关闭,此时再做校验已经来不及。
正确实现逻辑:
- 所有校验逻辑全部放在对话框的提交按钮事件最前面
- 校验失败时弹提示后直接return,不要设置
DialogResult,窗口就会保持打开状态 - 只有所有校验全部通过后,再设置
DialogResult = true,此时窗口才会关闭并返回结果给主窗口
内容的提问来源于stack exchange,提问作者tara
相关产品推荐
相关产品推荐

