【问题标题】:How to avoid multiple event fire when WPF page is opened again?再次打开 WPF 页面时如何避免多个事件触发?
【发布时间】:2017-02-03 17:00:16
【问题描述】:

我的 WPF 应用程序中有一个框架和几页。

我的导航是由按钮控制的。在每个按钮上,我都有单击处理程序,它使用一些参数创建新页面:

private void ButtonProductionAuto_OnClick(ref TechModbus, RoutedEventArgs e)
{
    FrameMain.Content = new PageProductionAuto(someobject, this);
}

private void ButtonProductionManual_OnClick(ref TechModbus, RoutedEventArgs e)
{
    FrameMain.Content = new PageProductionManual(someobject, this);
}

当我在页面之间切换时 - 以前的页面仍然存在于内存中,它们会对一些自定义事件做出反应。

(编辑)

这是我与事件相关的代码:

public PageProductionAuto(ref TechModbus modbus, MainWindow wnd)
{        
    // ...

    wnd.KeyDown += Wnd_KeyDown;
    wnd.KeyUp += Wnd_KeyUp;
    m.OnReadFinished += Modbus_OnReadFinished;

    // ...
}

我如何处置这些页面,或者如何避免在页面第二次打开时对我的事件造成双重触发?

【问题讨论】:

  • 向我们展示PageProductionAutoPageProductionManual的代码
  • @KosalaW 我已经添加了代码。

标签: c# wpf window dispose


【解决方案1】:

您应该在离开页面时取消注册事件。

然后,当这些对象(PageProductionAutoPageProductionManual)上没有更多引用时,GarbageCollector 将自行 "dispose"(它实际上不是处置)。

引用 MS: WPF 控件不实现 IDisposable 的原因是因为它们没有可处置的东西。他们没有要清理的句柄,也没有要释放的非托管资源。为确保您的内存得到清理,只需确保在您使用完控件后没有任何内容可以引用它们。

【讨论】:

  • 这不是问题的解决方案。 OP正在询问“如何处置”。
  • 但是不注销然后处置这些对象是一种非常非常非常糟糕的做法。这是我认为唯一合理的解决方案。
  • 是的。分离事件是一种很好的做法。但这个问题是关于如何处置,以及如何控制拥有多个实例。
  • 请提供该引用的来源 URL,并考虑将其格式化为带有 > 字符的实际引用。
  • 好的。更清楚地说:您不能处置 WPF 元素,因为它们没有理由可处置。如果你想这样做,你需要编写自己的 wpf 控件并实现 IDisposeable。
【解决方案2】:

您的问题不完整。但我可以回答部分关于“如何避免多个实例”的问题。要处置您的页面,您必须分离您的事件,将它们从“openedPages”集合中移除,并在可能的情况下处置。

List<object> openedPages = new List<object>();

private void ButtonProductionAuto_OnClick(object sender, RoutedEventArgs e)
{
    var page = openedPages.FirstOrDefault(p => p.GetType().Equals(typeof(PageProductionAuto)));
    if(page == null)
    {
        page = new PageProductionAuto(someobject, this);
        opendPages.Add(page);
    }
    else
    {
        page.SetObjects(someobject, this); // create a method to set "someObject" to your page.
    }

    FrameMain.Content = page;
}

【讨论】:

    【解决方案3】:

    为了避免这种情况,我做了一个有 2 个框架的窗口。我在每个帧中放置了每个源 XAML 之一,因此第 1 帧是 XAML 1,第 2 帧是 XAML 2。然后我只是将可见性编辑为折叠和可见。然后,您不会有任何页面更改或创建实例。您只需创建原始的 2 个实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2011-04-04
      • 2011-04-12
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多