我将数据从Form1
的一个WPF窗口传输到Form2
的另一个WPF窗口,但每次我将数据从Form2
传输到Form1
我必须关闭并打开Form1
。是否有替代方法可以在不关闭和打开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();
}
答案 0 :(得分:1)
在通常用于WPF应用程序的MVVM模式中,这可以通过多种方式实现。以下方式可能是最简单的方法:
1)代码隐藏文件中当前的代码将进入一种名为“ViewModel”的类中。这是一个不依赖于任何面向UI的对象的类,而是充当XAML视图的“DataContext”。这两个通过Xaml数据绑定表达式链接起来。为了使类至少成为ViewModel,它必须实现INotifyPropertyChanged接口。 Form1和Form2背后的代码都需要放在一个实现名为Form1ViewModel和Form2ViewModel的INotifyPropertyChanged的类中。
2)Form1ViewModel的实例可以订阅Form2ViewModel实例的更改,这样每次Form1属性更改时,Form2中的处理程序都可以捕获更改并更新它自己的匹配属性
3)Form1View.xaml和Form2View.xaml可以使用双向绑定表达式分别绑定到Form1ViewModel.cs和Form2ViewModels.cs的属性,这样每次Form1ViewModel.MyProperty都会更改(感谢Form2ViewModel的更新),任何绑定到Form1ViewModel.MyProperty的UI控件都将使用视图模型属性的新值进行更新。
编辑(如何在没有 MVVM的情况下执行此类操作)
我建议创建一个测试WPF项目。向名为“ChildWindow”的项目添加一个新窗口。将我的所有代码粘贴到文件后,运行该项目。单击“显示子表单”按钮。将两个窗户分开,以便可以并排查看。在MainWindows TextBox中键入一些文本,然后观看ChildWindow的文本框自动更新它的文本!
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);
}
}
}
答案 1 :(得分:0)
听起来你需要一个模态窗口。使用ShowDialog()而不是Show()
这是你想要的行为吗?
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();
}
如果你需要在form2可见时隐藏Form1
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
}
答案 2 :(得分:0)
以下是满足我需求的方法:
窗口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();
}
}