在子窗口和父窗口之间共享数据(C#WPF)

时间:2017-02-02 03:33:21

标签: c# wpf

情境: 三种形式:MainWindow,Positions,Calibration自我命名(MainWindow : Window等)

MainWindow创建三个对象的实例:

  • Vars:Model Vars = new Model();
  • 职位:Positions PositionsWindow = new Positions();
  • 校准:Calibration CalibrationWindow = new Calibration();

MainWindow中的按钮用于显示和隐藏子窗口。 MainWindow中的表单字段更新类Vars中的字段。

MainWindow代码:

 public partial class MainWindow : Window
 {

        Model Vars = new Model();
        Positions PositionsWindow = new Positions();
        Calibration CalibrationWindow = new Calibration();

        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
                PositionsWindow.Show();
        }

        private void TextBoxUpdate_Click(object sender, RoutedEventArgs e)
        {
                Vars.TestVar = TestBox.Text;
        }
}

问题:子窗口中的表单字段如何更新“Vars”类中的父表单字段和/或字段,即将数据从子节点传递到父节点并在父节点中触发操作形成的?

尝试:类似的问题建议传递主窗口this,例如:Positions PositionsWindow = new Positions();但是,这只适用于在方法中创建对象的情况。此时,PositionsWindow.Show();不再有效。即它仅适用于以单一方法创建和关闭的子窗口。

2 个答案:

答案 0 :(得分:1)

我不建议在构造函数之前初始化变量。不要习惯。 我会改变三个Windows中每一个的构造函数:

public partial class Model : Window{
    MainWindow MW;

    Model(MainWindow MW){
        this.MW = MW;
        // other constructor stuff
    }
}

PositionsCalibration执行相同的操作。

显然,在调用构造函数之前初始化Windows时,不能使用this,因为仍然没有this传递。

因此,在您的MainWindow中:

 public partial class MainWindow : Window
 {

        Model Vars; // = new Model(this); <- the constructor was not yet called, there is no this
        Positions PositionsWindow; // = new Positions();
        Calibration CalibrationWindow; // = new Calibration();

        MainWindow(){
            Vars = new Model(this);
            Positions = new Positions(this);
            CalibrationWindow = new Calibration(this);
        }

        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
                PositionsWindow.Show();
        }

        private void TextBoxUpdate_Click(object sender, RoutedEventArgs e)
        {
                Vars.TestVar = TestBox.Text;
        }
}

编辑:(完成问题的答案): 现在,如果您希望Windows相互更改内容,只需在MainWindow中创建更改每个Windows中的内容的函数。使用MW,您可以从任何子窗口调用这些函数

答案 1 :(得分:1)

对我来说,最好是使用基于订阅/发布者事件的方式,这是实现它的方法。 (我重新创建代码,以便您可以理解)

1)在您的子窗口中添加事件发布者。

public partial class ChildWindows : Window
{
    // the is the event publisher
    public event Action<string> ChildUpdated;

    public ChildWindows()
    {
        InitializeComponent();
    }

    private void updateParentBtn_Click(object sender, RoutedEventArgs e)
    {
        // pass the parameter.
        ChildUpdated(updateTb.Text);
    }
} 

2)在父窗口中订阅发布者。

    public partial class MainWindow : Window
{
    Model Vars;
    ChildWindows childWindows;
    public MainWindow()
    {
        InitializeComponent();
        Vars = new Model();
        childWindows = new ChildWindows();

        //this is the event subscriber.
        childWindows.ChildUpdated += ChildWindows_ChildUpdated;
    }

    //do whatever you want here.
    void ChildWindows_ChildUpdated(string obj)
    {
        // Update your Vars and parent
        Vars.TestVar = obj;
        updateLbl.Content = Vars.TestVar;
    }

    private void openButton_Click(object sender, RoutedEventArgs e)
    {
        childWindows.Show();
    }

    private void textBoxUpdate_Click(object sender, RoutedEventArgs e)
    {

    }
}

3)在这种情况下,当我在子窗口中输入文本框内部并按下按钮时,它将显示在我父窗口内的标签上。

P / S:我已将ParentUpdated更改为ChildUpdated。感谢@Adrian的建设性反馈

example