如何在 WPF 的数据网格中显示用户输入?

How to display user inputs in data grid in WPF?

我在主 window 中有一个数据网格。当我单击“添加”按钮时,它会打开一个名为“AddDetails”的新 window。它需要用户输入,例如姓名、年龄、城市。我在 AddDetails.xaml.cs 中创建了一个 class “PersonalInfo” 来定义字段。当我单击“AddDetails”windows 中的“提交”按钮时,我的数据网格应使用用户输入值进行更新。我需要有关如何在不实施 MVVM 架构的情况下执行此操作的帮助。问题是当我点击“提交”按钮时,它每次都会打开一个新的 window 并在网格中添加详细信息。此外,先前添加的输入不存在。我想要的是在主 window.

中显示所有用户输入

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="Name" Binding="{Binding _name}" Width="130"/>
            <DataGridTextColumn Header="Age" Binding="{Binding _name}" Width="130"/>
            <DataGridTextColumn Header="City" Binding="{Binding _name}" Width="*"/>
        </DataGrid.Columns>
    </DataGrid>

    <Button x:Name="ADD" Click="ADD_Click" Content="ADD" HorizontalAlignment="left" VerticalAlignment="Top" Margin="127,335,0,0" Width="74"/>
</Grid>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
       
    }

    public MainWindow(PersonalInfo personal)
    {
        InitializeComponent();
        DataGrid1.Items.Add(personal);

    }


    private void ADD_Click(object sender, RoutedEventArgs e)
    {
        AddDetails addDetails = new AddDetails();
        addDetails.Show();
    }

    
}

AddDetails.xaml:

<Window x:Class="WPF_Practice.AddDetails"
    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="AddDetails" Height="450" Width="800">
<Grid>
    <Button Content="Submit" HorizontalAlignment="Left" Margin="276,248,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    <Label Content="Name" HorizontalAlignment="Left" Margin="216,101,0,0" VerticalAlignment="Top"/>
    <Label Content="Age" HorizontalAlignment="Left" Margin="216,147,0,0" VerticalAlignment="Top"/>
    <Label Content="City" HorizontalAlignment="Left" Margin="216,186,0,0" VerticalAlignment="Top"/>
    <TextBox x:Name="Name" HorizontalAlignment="Left" Height="23" Margin="334,113,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="120"/>
    <TextBox x:Name="Age" HorizontalAlignment="Left" Height="23" Margin="334,159,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="120"/>
    <TextBox x:Name="City" HorizontalAlignment="Left" Height="23" Margin="334,198,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="120"/>

</Grid>

AddDetails.xaml.cs:

public partial class AddDetails : Window
{

    PersonalInfo personal = new PersonalInfo();
    public AddDetails()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.Hide();
        personal.name = Name.Text;
        personal.age = Convert.ToInt32(Age.Text);
        personal.city = City.Text;

        MainWindow mainWindow = new MainWindow(personal);
        mainWindow.Show();

    }

    public class PersonalInfo
    {
        public string name { get; set; }
        public int age { get; set; }
        public string city { get; set; }
    }
}

这是我对对话框的实现:(EDIT)

private void ADD_Click(object sender, RoutedEventArgs e)
{

    Dialogue dialogue = new Dialogue();
    if(dialogue.ShowDialog() == true)
 {

    PersonalInfo._name = dialogue.Name.Text;
    PersonalInfo._age= Convert.ToInt32(dialogue.Age.Text);
    PersonalInfo._city= dialogue.CityText;

  if(dialogue.Name.Text.Length == 0)

  {

    MessageBox.Show(“Please fill all the details”);

  } 

    DataGrid1.Items.Add(personalInfo);

  }

正在显示消息框。但是当它这样做时,对话 window 会自动关闭。当显示消息框时,我不希望对话 window 关闭。这样,当我在消息框上单击“确定”时,我应该能够返回我的对话 window 并编辑字段。

提前致谢。

您当前在 windows 之间导航的方式,在按下提交后 MainWindow 的新实例是预期的(这也意味着,您之前的数据将被丢弃):

每次您创建新的 AddDetails window 时,该 AddDetails 实例的 PersonalInfo 都会分配一个全新的对象。

PersonalInfo personal = new PersonalInfo();

显示您的 AddDetails 页面时,您每次都创建一个新的 AddDetails 对象:

private void ADD_Click(object sender, RoutedEventArgs e)
{
    AddDetails addDetails = new AddDetails();
    addDetails.Show();
}

每当您从此 AddDetails Window 导航回来时,您都会创建一个全新的 MainWindow 以导航回:

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.Hide();
    personal.name = Name.Text;
    personal.age = Convert.ToInt32(Age.Text);
    personal.city = City.Text;

    MainWindow mainWindow = new MainWindow(personal); //<-- new MainWindow instance
    mainWindow.Show();
}

有多种方法可以避免这种情况:

  1. 使用新的 Window 实例并在构造函数或加载事件中填充它们的数据。如果您想将数据存储在 Window 个实例之间,则必须以持久的方式存储它们。每次卸载 MainWindow 对象时,其中的所有数据都会随之消失,包括对其他 Windows 的引用。一个例外是静态字段,或者直接存储在您的应用程序 class 中的任何数据。

  2. 让您的 window 实例本身以上述方式存储。如果您有一个 MainWindow 类型的静态 属性 并在应用程序运行时开始时将当前 Window 分配给它,您可以简单地重用它。

这两种解决方案都没有考虑像 WPF 这样的大型框架所带来的功能。我的建议是切换到以下任一解决方案:

1:使用导航Window。如果您的 MainWindow 是 NavigationWindow 而不仅仅是 Window,您可以非常轻松地在页面之间导航。 AddDetails 反过来不会是 Window,它会是一个页面,例如:

`public partial class AddDetails : Page`

`<Page x:Class="WPF_Practice.AddDetails"...`

2:使用对话框而不是 Window 来显示您的 AddDetails。对话框是一个非常有用的 WPF 功能,您可以在其中显示任何控件,就像显示警报一样。它将在当前的 window 之上显示一个新的 window,必须在初始 window 可以再次与之交互之前提交,例如:

private void ADD_Click(object sender, RoutedEventArgs e)
{
    AddDetails addDetails = new AddDetails();
    if (addDetails.ShowDialog() == true)
    {
        //do something after the user pressed "submit"
    }
}

在这种情况下,您所要做的就是告诉您的 AddDetails 对话框,当它被认为完成时。例如:

private void Button_Click(object sender, RoutedEventArgs e)
{
    DialogResult = true; //true means success, false means dialog was canceled
}