【问题标题】:wpf events between two windows两个窗口之间的 wpf 事件
【发布时间】:2016-10-02 14:49:22
【问题描述】:

有人可以为我说明如何设置这样的逻辑:

我有一个 WPF 控件。当一个按钮被按下时,它会做两种可能的事情之一。

A.它检查是否已加载不同的 WPF 窗口。如果是,它会触发该窗口的 Print 方法。 B. 它检查是否已加载不同的 WPF 窗口。如果不是,它会实例化那个窗口,然后触发它的 Print 方法。

我很难理解两个 WPF 控件/Windows 之间的事件系统。这对我来说是一个相对较新的东西,所以如果有人带我完成这个,我将不胜感激。

附言。这不是家庭作业,而是我的新爱好。如果这完全是一个菜鸟问题,那么只需将我指向一个资源,这样我就可以自学了。

干杯!

【问题讨论】:

  • 你的问题太宽泛了。您需要提供一个很好的minimal reproducible example 来清楚地说明您的情况。我会指出,您似乎错误地看待问题。也就是说,打印命令应该属于知道如何打印的视图模型,并且您不必导航事件系统来调用视图模型上的命令来打印。 WPF 中的 UI 和事件路由可供用户与视图交互,而视图又与视图模型交互。除了与用户交互直接相关的功能外,视图本身不应实现功能。
  • 如何为您的案例使用观察者 - 订阅者设计模式。我认为这将是一个很好的解决方案

标签: c# wpf


【解决方案1】:

首先,您将通过什么方式检查新打开的Window 是否是您需要的?

您可以通过比较他们的HandleType公共类 MyWindowWithPrintMethod : Window)来做到这一点。

有多种方法可以做到这一点。

我建议我的简单方法,专注于 WPF 方式,以尽可能最简单的方式解决您的目的。

    MyWindowWithPrintMethod obj_MyWindowWithPrintMethod;
    private void btnNewWindow_Click(object sender, RoutedEventArgs e)
    {
       obj_MyWindowWithPrintMethod = new MyWindowWithPrintMethod();
       obj_MyWindowWithPrintMethod.Show();
    }

    private void btnCheckNewWindow_Click(object sender, RoutedEventArgs e)
    {
       WindowInteropHelper tgtWindow = new WindowInteropHelper(obj_MyWindowWithPrintMethod);

       foreach (Window w in Application.Current.Windows)
       { 
          // Compare Handle
          WindowInteropHelper wih = new WindowInteropHelper(w);
          if (wih.Handle == tgtWindow.Handle)
          { 
            ((MyWindowWithPrintMethod)w).Print();
          }

          // Compare Type
          if (w.GetType() == typeof(MyWindowWithPrintMethod))
          {
            ((MyWindowWithPrintMethod)w).Print();
          }
       }
    }

MyWindowWithPrintMethod.cs

     public class MyWindowWithPrintMethod : Window
     {
         public void Print()
         {
            MessageBox.Show("Print invoked !");
         }
     }

【讨论】:

    【解决方案2】:

    这个answer 来自这个question 关于来自2 个窗口的事件可能会有所帮助:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }
    
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Child childWindow = new Child();
            childWindow.MyEvent += new EventHandler(childWindow_MyEvent);
    
            childWindow.ShowDialog();
        }
    
        void childWindow_MyEvent(object sender, EventArgs e)
        {
            // handle event
            MessageBox.Show("Handle");
        }
    }
    

    子窗口

    public partial class Child : Window
    {
        // define event
        public event EventHandler MyEvent;
    
        protected void OnMyEvent()
        {
            if (this.MyEvent != null)
                this.MyEvent(this, EventArgs.Empty);
        }
    
        public Child()
        {
            InitializeComponent();
    
            this.Loaded += new RoutedEventHandler(Child_Loaded);
        }
    
        void Child_Loaded(object sender, RoutedEventArgs e)
        {
            // call event
            this.OnMyEvent();
        }
    }
    

    上面的代码展示了如何设置一个从一个窗口到另一个窗口的事件。但是,您可能只想在另一个窗口中调用一个方法。对于example

    public void AddNewUser()
    {
        Window2 window = new Window2();
        if (window.ShowDialog() == true)
        {
            // Update DataGrid
            RefreshDataGrid();
        }
    }
    

    如果您决心坚持活动,那么您应该阅读WPF routed events

    【讨论】:

    • 如何为您的案例使用观察者 - 订阅者设计模式。我认为这将是一个很好的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多