将数据从子窗口传递到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"); } }