将数据从子窗口传递到MainWindow TextBlock

在此示例中, MainWindow有一个打开Window2的按钮。

Window2有一个写“Hello,World!”的按钮。 到MainWindow文本块。

项目来源: https : //www.dropbox.com/s/jegeguhycs1mewu/PassData.zip?dl = 0

传递数据


将数据从Window2传递到MainWindow的正确方法是什么?

 private MainWindow mainwindow; public MainWindow mainwindow { get; private set; } public Window MainWindow { get; set; } private object mainwindow { get; private set; }; private MainWindow mainwindow = ((MainWindow)System.Windows.Application.Current.MainWindow); this.mainwindow = mainwindow; 

主窗口

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // Open Window 2 private void buttonWindow2_Click(object sender, RoutedEventArgs e) { Window2 window2 = new Window2(this); window2.Left = Math.Max(this.Left - window2.Width, 0); window2.Top = Math.Max(this.Top - 0, 0); window2.ShowDialog(); } } 

窗口2

 public partial class Window2 : Window { private MainWindow mainwindow; public Window2(MainWindow mainwindow) { InitializeComponent(); this.mainwindow = mainwindow; } // Write Message to MainWindow private void buttonMessage_Click(object sender, RoutedEventArgs e) { mainwindow.textBlockMessage.Text = "Hello, world!"; } } 

您正在寻找的答案是基于实现的,并且在很大程度上取决于您希望Window2作为一个类做什么。


 private MainWindow mainwindow; 

这是可以接受的。

 public MainWindow mainwindow { get; private set; } 

这可以工作,但不尊重命名约定,因为它是一个属性。 通常,您可以使用它来封装字段或轻松访问计算值。

 public Window MainWindow { get; set; } 

这在您的上下文中是不可接受的,因为Window不包含textBlockMessage

 private object mainwindow { get; private set; }; 

由于与上述相同的原因,这也不起作用。

 private MainWindow mainwindow = ((MainWindow)System.Windows.Application.Current.MainWindow); 

这可以工作,甚至可以让你不保留一个字段来引用Window2实例中的MainWindow实例。 每次单击按钮时仍需要获取MainWindow


然而,另一种有趣的做法是在instanciation时将处理程序传递给子窗口:

主窗口

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // Open Window 2 private void buttonWindow2_Click(object sender, RoutedEventArgs e) { Window2 window2 = new Window2(); // No need to give a reference to the child window anymore window2.setClickHandler((obj, ev) => { textBlockMessage.Text = "Hello, world!"; // Direct access to the textblock. }); window2.Left = Math.Max(this.Left - window2.Width, 0); window2.Top = Math.Max(this.Top - 0, 0); window2.ShowDialog(); } } 

窗口2

 public partial class Window2 : Window { public Window2() { InitializeComponent(); } public void setClickHandler(RoutedEventHandler handler) { // The handler is given to the click event. buttonMessage.Click -= handler; buttonMessage.Click += handler; } } 

而且你的Window2类不需要知道MainWindow

“正确”的方式通常取决于您的需求和环境。 但一般来说,使用委托在窗口之间传递数据是一种常见的标准做法。

假设您要传递的数据是一个字符串。 在主窗口中,您要创建一个允许您传递字符串的委托。 然后,您创建该委托类型的实例并订阅匹配的方法。 然后,当您打开辅助窗口时,将该委托传递到辅助窗口。

 public delegate void DataTransfer(string data); public partial class MainWindow : Window { public DataTransfer transferDelegate; public MainWindow() { InitializeComponent(); transferDelegate += new DataTransfer(DataMethod); } public void DataMethod(string data) { // Do what you want with your data. } private void button1_Click(object sender, EventArgs e) { Window2 win = new Window2(transferDelegate); win.Show(); } } 

现在,当您在辅助窗口中调用该委托时,将调用Form1的DataMethod() ,因此您可以在窗口之间传递信息。

您的辅助窗口实现应如下所示:

 public partial class Window2 : Window { DataTransfer transferDel; public Window2(DataTransfer del) { InitializeComponent(); transferDel = del; } private void button1_Click(object sender, EventArgs e) { string data = "Hello, World!"; // Your string data to pass. transferDel.Invoke(data); } } 

如您所见,当您调用传递的委托时,它会调用主程序中的相应方法。

这种方法的一个突出优点是你不需要将MainWindow的实例传递给你的Window2,你只需使用委托和订阅的方法在两个windows实例之间传递数据。

您可以在窗口2中声明一个委托,并传递一个在窗口2中按下按钮时可以执行的function。

  public delegate void SendMessage(string Message); public SendMessage mainWindowDel = null; 

使您的构造函数接受委托

  public Window2(SendMessage del) { mainWindowDel = del; } 

通过传递函数作为参数来创建窗口2

  public void showMessage(string Message) { if(!string.IsNullOrWhiteSpace(Message)) textBlockMessage.Text = Message; } private void buttonWindow2_Click(object sender, RoutedEventArgs e) { // Open Window 2 //Window2 window2 = new Window2(this); Window2 window2 = new Window2(showMessage); window2.Left = Math.Max(this.Left - window2.Width, 0); window2.Top = Math.Max(this.Top - 0, 0); window2.ShowDialog(); } 

按下按钮时给代表打电话

 // Write Message to MainWindow private void buttonMessage_Click(object sender, RoutedEventArgs e) { mainWindowDel("Hello, world!"); } 

您可以将MainWindow的datacontext设置为一个对象,您可以在创建它时将其传递给Window2,并将其datacontext设置为同一对象。

在该对象中可以创建可以在两个窗口中使用的字符串属性。 如果你实现了INotifyPropertyChanged接口,两个窗口都会知道该字符串何时更新。

另一种方法

主窗口

  public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private bool DisplayText(string displayText) { txt_Main.Text = displayText; return true; } private void Button_Click(object sender, RoutedEventArgs e) { Window2 win2 = new Window2(DisplayText); win2.ShowDialog(); } } 

窗口2

  public partial class Window2 : Window { private Func mainWindowMethod; public Window2(Func displayMethod) { InitializeComponent(); this.mainWindowMethod = displayMethod; } private void Button_Click(object sender, RoutedEventArgs e) { this.mainWindowMethod("Hello World"); } }