C# - 在 WPF 中从子窗口返回变量给父窗口

8

我有一个名为form1的主窗口,在form1中有一个按钮,当按下该按钮时,它会打开form2(form2.ShowDialog())。在form2中,我有一个名为“Check”的按钮。 当用户单击“Check”时,它应该进行一些验证,如果成功则创建一个字符串对象并将其返回给form1。如何实现这个想法呢?我不想在用户关闭窗口时返回任何内容。

3个回答

12
在你的第二个窗口中创建一个事件,使事件委托的参数包含你想要传递的任何信息:
public class Popup : Window
{
    public event Action<string> Check;

    public void Foo()
    {
        //fire the event
        if (Check != null)
            Check("hello world");
    }
}

然后主窗口可以订阅该事件以对信息执行其想要的操作:

public class Main : Window
{
    private Label label;
    public void Foo()
    {
        Popup popup = new Popup();
        popup.Check += value => label.Content = value;
        popup.ShowDialog();
    }
}

1
抢先一步了。就我个人而言,我喜欢这种窗口间通信的方法。然而,还有另一种方法也很不错,我会在下面发布一个包含它的答案。 - Joe Brunscheon
运行完美无缺。谢谢! - barack o mama
如果我有两个字符串怎么办?如何编写代码?popup.Check += value => label.Content = value, label2.Content = value; ?? - Sizzling Code
@SizzlingCode 如果您使用语句lambda而不是表达式lambda,或者只是将一个赋值的结果分配给下一个标签。 - Servy
1
谢谢您先生。但是如果可以的话,您能否给出一个例子呢?因为我对C#和WPF应用程序真的很新。我从PHP开发转过来。 我已经发布了一个关于此问题的问题。 http://stackoverflow.com/questions/31877458/wpf-delegate-get-two-values如果可以的话,请看一下我的问题。 - Sizzling Code

3
这个答案虽然不是完全针对问题,但对于那些在谷歌搜索如何在窗口间通信的人来说会更有用:

没有必要设置事件来访问您应用程序的主窗口对象。您只需在弹出代码中调用它们即可:

((MainWindow)Application.Current.MainWindow).textBox1.Text = "Some text";

0

这可以通过几种方式实现。Servy发布的方法非常好,可以完成您需要的任务。我更喜欢将Action<sting>作为参数传递给构造函数并命名为callback,以便清楚地了解它的用途,但这只是个人偏好。

另一种很好的方法是通过消息传递来完成。MVVMLight Toolkit提供了一个非常好的功能来完成此类任务。

步骤1:创建一个强类型消息:

public class MyMessage : MessageBase
{
    //Message payload implementation goes here by declaring properties, etc...
}

步骤2:确定在何时何地发布该消息。

public class PublishMessage
{
    public PublishMessage(){
    }

    public void MyMethod()
    {
        //do something in this method, then send message:
        Messenger.Default.Send(new MyMessage() { /*initialize payload here */ });
    }
}

步骤三:现在您正在发送消息,您需要能够接收该消息:

public class MessageReceiver
{
    public MessageReceiver()
    {
        Messenger.Default.Register<MyMessage>(this, message => Foo(message));
    }

    public void Foo(MyMessage message)
    {
        //do stuff
    }
}

1
虽然你没有提供足够的实现来确切说明,但看起来你在这里拥有的是一个可由任何人触发的公共静态事件。当它们遇到消息时,其他类型不再可发现其要订阅的事件,也没有内置指示表明其含义、谁“负责”它、与什么相关等。还有可能(而且很容易错误地)触发不正确的消息,在两个不同的位置引起问题。我真的看不到这里有任何优势。 - Servy
我并没有说这是一个优势,只是另一种做法。在这种情况下,通过找到你的消息并检查谁使用它,很容易找出谁订阅了什么消息。它是强类型的,所以你发送和接收的消息是毫无疑问的。对于消息的处理责任落在消息接收者身上。发送者只是举起一面旗帜表示已经完成了某些事情。发送不当的消息相当困难,但是有可能,只需要开发人员注意即可。 - Joe Brunscheon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接