I have a data grid in the main window. When I click on the “Add” button, it opens up a new window called “AddDetails”. It takes user inputs such as Name, Age, City. I created a class “PersonalInfo” in AddDetails.xaml.cs to define the fields. When I click the “submit” button in the “AddDetails” windows, my data grid should be updated with the user input values. I need help on how to do it without implementing MVVM architecture. The problem is when I click on “submit” button, it opens up a new window every time and add the details in the grid. Also, the previously added inputs are not present. What I want is to display all the user inputs in the main 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>
</Window>
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>
</Window>
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; }
}
}
Thanks in advance.
CodePudding user response:
The way you are currently navigating between windows, a new instance of MainWindow after pressing submit is expected (which also means, your previous data will be discarded):
Every time you create a new AddDetails
window, the PersonalInfo
of that AddDetails instance is assigned a completely new object.
PersonalInfo personal = new PersonalInfo();
When showing your AddDetails page, you create a new AddDetails object every time:
private void ADD_Click(object sender, RoutedEventArgs e)
{
AddDetails addDetails = new AddDetails();
addDetails.Show();
}
Whenever you navigate back from this AddDetails Window, you create an entirely new MainWindow to navigate back to:
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();
}
There are multiple ways to avoid this:
work with new Window instances and populate their data in the constructor or load event. If you want to keep your data stored between Window instances, you'll have to store them in a persistent manner. Every time your MainWindow objects are unloaded, all the data inside them disappears with them, including references to other Windows. An exception to that would be static fields for example, or any data stored in your App class directly.
keep your window instances themselves stored in the above manner. If you had a static property of type MainWindow and assigned it the current Window at the start of the application runtime, you could simply reuse that.
Both of those solutions don't take into account the features a large framework like WPF brings with it. My recommendation would be to switch to either of the following solutions:
1: Use a NavigationWindow. If your MainWindow were a NavigationWindow instead of just a Window, you could very easily navigate between pages. AddDetails in turn wouldn't be a Window, it would be a page, eg:
`public partial class AddDetails : Page`
`<Page x:Class="WPF_Practice.AddDetails"...`
2: Use a Dialog instead of a Window to display your AddDetails. Dialogues are a very useful WPF feature, where you can display any control like you would an alert. It will display a new window on top of the current one, that has to be submitted before the initial window can be interacted with again, eg:
private void ADD_Click(object sender, RoutedEventArgs e)
{
AddDetails addDetails = new AddDetails();
if (addDetails.ShowDialog() == true)
{
//do something after the user pressed "submit"
}
}
In this case, all you have to do is tell your AddDetails dialog, when it is considered finished. For example:
private void Button_Click(object sender, RoutedEventArgs e)
{
DialogResult = true; //true means success, false means dialog was canceled
}