Reputation: 137
I'm transferring data from one WPF window form Form1
to another WPF window form Form2
, but every time I transfer data from Form2
to Form1
I have to close and open Form1
. Is there an alternative to transfer data without closing and opening Form1
?
FORM1
private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
SelectSeller frmSelectSeller = new SelectSeller();
frmSelectSeller.Show();
this.Hide();
}
FORM2
private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
clsCreateInvoice.S_Code = drv["B_Code"].ToString();
clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," +
drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
CreateInvoice frmCreateInvoice = new CreateInvoice();
frmCreateInvoice.txtSellerCode.Text = drv["B_Code"].ToString();
frmCreateInvoice.lblSellerNameAddress.Text = drv["B_Name"].ToString() + " ," +
drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
frmCreateInvoice.Show();
this.Hide();
}
Upvotes: 1
Views: 1645
Reputation: 137
Here is approach i follow to fullfill my need :
Window 1
private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
SelectSeller frmSelectSeller = new SelectSeller(this);
frmSelectSeller.Show();
this.Hide();
}
Window 2
public partial class SelectSeller : Window
{
CreateInvoice _frmCreateInvoice;
public SelectSeller(CreateInvoice frmCreateInvoice)
{
InitializeComponent();
_frmCreateInvoice = frmCreateInvoice;
}
private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
clsCreateInvoice.S_Code = drv["B_Code"].ToString();
clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
_frmCreateInvoice.txtSellerCode.Text = drv["B_Code"].ToString();
_frmCreateInvoice.lblSellerNameAddress.Text = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
this.Hide();
}
}
Upvotes: 0
Reputation: 878
In the MVVM pattern which is often used for WPF applications, this can be accomplished several ways. The following way is probably the easiest:
1) The code that is currently in your code-behind file would go into in a type of class called a "ViewModel". This is a class that has no dependencies on any UI-oriented objects but instead acts as a "DataContext" for a XAML view. The two are linked up through Xaml databinding expressions. In order for a class to be a ViewModel at minimum it must implement the INotifyPropertyChanged interface. Both the code behind Form1 and Form2 would need to be put into a class that implements INotifyPropertyChanged called Form1ViewModel and Form2ViewModel.
2) Instances of Form1ViewModel could subscribe to changes on an instances of Form2ViewModel such that every time a Form1 property changed, a handler in Form2 could catch the change and update it's own matching property
3) Form1View.xaml and Form2View.xaml can use two-way binding expressions to bind to the properties of Form1ViewModel.cs and Form2ViewModels.cs respectively such that every time Form1ViewModel.MyProperty changes (thanks to an update from Form2ViewModel), any UI Controls that are bound to Form1ViewModel.MyProperty will update with the new value of the view model property.
Edit (How to do this sort of thing without MVVM):
I recommend creating a test WPF project. Add a new Window to the project called "ChildWindow". After pasting all of my code into the files, run the project. Click the button to "Show Child Form". Separate the two windows so they can be viewed side by side. Type some text into MainWindows TextBox and watch ChildWindow's textbox update it's text automatically!
MainWindow.xaml:
<Window x:Class="Wpf_2FormSync.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="82*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding MyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<Button Click="Button_Click_1" Grid.Row="1" >Show Child Form</Button>
<Button Grid.Row="2" Click="Button_Click_2" >Update Child Window</Button>
</Grid>
</Window>
MainWindow.xaml.cs:
using System;
using System.ComponentModel;
using System.Windows;
namespace Wpf_2FormSync
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ChildWindow _childWindow = null;
private string _myName = "";
public string MyName
{
get { return _myName; }
set
{
if (value == _myName) return;
_myName = value;
NotifyOfPropertyChanged("MyName");
if (_childWindow != null)
_childWindow.MyName = value;
}
}
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_childWindow = new ChildWindow();
_childWindow.Show();
_childWindow.MyName = "John";
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyOfPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
if (_childWindow != null)
_childWindow.MyName = this.MyName;
}
}
}
ChildWindow.xaml:
<Window x:Class="Wpf_2FormSync.ChildWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ChildWindow" Height="300" Width="300" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="112*"/>
<RowDefinition Height="157*"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding MyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0"></TextBox>
<Button Grid.Row="1" Click="Button_Click_1">Show</Button>
</Grid>
</Window>
ChildWindow.xaml.cs:
using System.ComponentModel;
using System.Windows;
namespace Wpf_2FormSync
{
/// <summary>
/// Interaction logic for ChildWindow.xaml
/// </summary>
public partial class ChildWindow : Window, INotifyPropertyChanged
{
private string _myName = "";
public string MyName
{
get { return _myName; }
set
{
if (value == _myName) return;
_myName = value;
NotifyOfPropertyChanged("MyName");
}
}
public ChildWindow()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyOfPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
MessageBox.Show(MyName);
}
}
}
Upvotes: 1
Reputation: 1108
Sounds like you need a modal window. Use ShowDialog() instead of Show()
Is this the behavior you want?
FORM1:
private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
SelectSeller frmSelectSeller = new SelectSeller();
frmSelectSeller.ShowDialog();
this.txtSellerCode.Text = frmSelectSeller.SellerCode;
this.lblSellerNameAddress.Text = frmSelectSeller.SellerNameAddress
}
FORM2:
//add these public properties
public string SellerCode {get; set;}
public string SellerNameAddress {get; set;}
private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
clsCreateInvoice.S_Code = drv["B_Code"].ToString();
clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
SellerCode = drv["B_Code"].ToString();
SellerNameAddress = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
this.Close();
}
if you need to hide Form1 while form2 is visible
private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
SelectSeller frmSelectSeller = new SelectSeller();
this.Hide();
frmSelectSeller.ShowDialog();
this.Show();
this.txtSellerCode.Text = frmSelectSeller.SellerCode;
this.lblSellerNameAddress.Text = frmSelectSeller.SellerNameAddress
}
Upvotes: 0