在子窗口和父窗口(C#WPF)之间共享数据
场景: 三种形式:主窗口、位置、校准自名(在子窗口和父窗口(C#WPF)之间共享数据,c#,wpf,C#,Wpf,场景: 三种形式:主窗口、位置、校准自名(MainWindow:Window等) MainWindow创建三个对象的实例: 变量:Model变量=新模型() 职位:Positions PositionsWindow=新职位() 校准:校准校准窗口=新校准() 主窗口中的按钮用于显示和隐藏子窗口。主窗口中的表单字段更新类变量中的字段 主窗口代码: public partial class MainWindow : Window { Model Vars = new Mod
MainWindow:Window
等)
MainWindow创建三个对象的实例:
- 变量:
Model变量=新模型()代码>
- 职位:
Positions PositionsWindow=新职位()代码>
- 校准:
校准校准窗口=新校准()代码>
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”中的字段,即从子表单向父表单传递数据并触发父表单中的操作
尝试:一个类似的问题建议通过主窗口
此
,例如:位置swindow=new Positions()但是,这仅在方法中创建对象时有效。此时,PositionsWindow.Show()代码>不再有效。i、 e.它只适用于在单个方法中创建和关闭的子窗口。我不建议在构造函数之前初始化变量。别习惯了。
我将更改三个窗口中每个窗口的构造函数:
public partial class Model : Window{
MainWindow MW;
Model(MainWindow MW){
this.MW = MW;
// other constructor stuff
}
}
对位置
和校准
执行相同的操作
显然,在调用构造函数之前初始化窗口时不能使用this
,因为仍然没有this
要传递
因此,在主窗口中:
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;
}
}
公共部分类主窗口:窗口
{
Model Vars;//=new Model(this);我不建议在构造函数之前初始化变量。不要习惯于这样。
我将更改三个窗口中每个窗口的构造函数:
public partial class Model : Window{
MainWindow MW;
Model(MainWindow MW){
this.MW = MW;
// other constructor stuff
}
}
对位置
和校准
执行相同的操作
显然,在调用构造函数之前初始化窗口时不能使用this
,因为仍然没有this
要传递
因此,在主窗口中:
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;
}
}
公共部分类主窗口:窗口
{
Model Vars;//=new Model(this);对我来说,最好的方法是使用基于订阅/发布者事件的方式,下面是实现方法。(我重新创建代码以便您能够理解)
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);
}
}
3) 在这种情况下,当我在子窗口的文本框内键入并按下按钮时,它将出现在父窗口内的标签上
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)
{
}
}
p/S:我已将ParentUpdated更改为ChildUpdated。感谢@Adrian的建设性反馈
对我来说,最好的方法是使用基于订阅/发布者事件的方式,下面是实现这一点的方法。(我重新创建代码以便您能够理解)
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);
}
}
3) 在这种情况下,当我在子窗口的文本框内键入并按下按钮时,它将出现在父窗口内的标签上
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)
{
}
}
p/S:我已将ParentUpdated更改为ChildUpdated。感谢@Adrian的建设性反馈
虽然这个模式在我看来是正确的,我也会这么做,但我会有点迂腐,说我会把这个事件命名为ChildUpdated
而不是ParentUpdated
,因为当孩子更新时,家长会订阅,然后从孩子那里收到更改的值。@Adrian是的,我同意你的说法,谢谢对于注释,我将相应地进行调整:)虽然模式在我看来是正确的,也是我将要做的,但我将有点迂腐,我将把事件命名为ChildUpdated
notParentUpdated
,因为当孩子更新时,家长正在订阅,然后从chi接收更改的值ld。@Adrian是的,我同意你的意见,谢谢你的评论,我会相应地调整:)这会起作用,但会使子窗口与父窗口紧密耦合。如果你想更改父窗口显示数据的方式,这会给你带来更多的工作。如果你想在不同的父窗口上使用同一窗口,这也会成为一个问题。@Ad如果要更改父级显示数据的方式,则需要执行更多的工作。如何?父级实现一个方法,该方法更改子级要更改的内容,子级可以使用MW.whateverMethod()
不同父窗口上的同一个窗口
。这是真的,但询问者没有说他想要。无论如何,对于复杂的应用程序,尤其是多进程的应用程序,这根本无法工作。在这种情况下,我更愿意使用WCF。他的应用程序只有多个线程(对于每个窗口)答案应该足够了。这样说,如果您不想再在主窗口上显示PositionsWindow的值,而是在CalibrationsWindow上,您必须更改PositionsWindow以在构造函数中使用CalibrationsWindow。虽然您可能认为这本身并不重要,但可以将其乘以更多窗口,然后hings变得更加困难。因此,虽然我说这会起作用并解决问题,但这并不是最好的解决方案。因为如果你一开始就能够以正确的方式做某件事,为什么要做两次呢?我们都应该做被认为是最佳实践的事情。@Adrian你必须改变位置进行校准构造函数中的窗口
这不是真的。你不必改变你说的方式。MainWindow
包含三个窗口的实例。如果他们想改变彼此的内容,可以让他们的父窗口(MainWindow
)您只需添加PositionsWindow
将调用MW
的方法,以便main窗口