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

时间:2017-08-18 01:25:11

标签: c# wpf visual-studio

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

Window2有一个按钮,用于编写" Hello,World!"到MainWindow文本块。

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

Pass Data

将数据从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();
    }
}

Window 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!";
    }
}

5 个答案:

答案 0 :(得分:1)

您正在寻找的答案非常基于实施,并且在很大程度上取决于您希望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);

这样可行,甚至可以让您不在一个字段中引用MainWindow个实例中的Window2实例。每次点击按钮时仍然需要MainWindow

另一种有趣的方法是做你正在做的事情就是简单地将处理程序传递给子窗口:

<强>主窗口

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

答案 1 :(得分:1)

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

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

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 :(得分:1)

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

 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!");
        }

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

另一种方法

<强>主窗口

 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<string, bool> mainWindowMethod;

        public Window2(Func<string, bool> displayMethod)
        {
            InitializeComponent();
            this.mainWindowMethod = displayMethod;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.mainWindowMethod("Hello World");
        }
    }