再次打开 WPF 页面时如何避免触发多个事件?
How to avoid multiple event fire when WPF page is opened again?
我的 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;
// ...
}
如何处理这些页面或如何避免在第二次打开页面时重复触发我的事件?
您应该在离开页面时注销事件。
当这些对象(PageProductionAuto
和 PageProductionManual
)不再有引用时,GarbageCollector 将 "dispose"
(实际上不是处理)自行处理。
引用 MS:
WPF 控件不实现 IDisposable 的原因是因为它们没有可处理的内容。它们没有要清理的句柄,也没有要释放的非托管资源。为确保您的记忆得到清理,只需确保在您使用完控件后没有任何内容引用它们。
您的问题不完整。但我可以回答其中 "how to avoid multiple instances" 部分的问题。要处理您的页面,您必须分离您的事件,将它们从 "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;
}
我为避免这种情况所做的是我有一个 window,里面有 2 个帧。我在每个帧中放置了每个源 XAML 之一,因此第 1 帧是 XAML 1,第 2 帧是 XAML 2。然后我只是将可见性编辑为折叠和可见。那么您没有任何页面更改或创建实例。您只需创建原始的 2 个实例。
我的 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;
// ...
}
如何处理这些页面或如何避免在第二次打开页面时重复触发我的事件?
您应该在离开页面时注销事件。
当这些对象(PageProductionAuto
和 PageProductionManual
)不再有引用时,GarbageCollector 将 "dispose"
(实际上不是处理)自行处理。
引用 MS: WPF 控件不实现 IDisposable 的原因是因为它们没有可处理的内容。它们没有要清理的句柄,也没有要释放的非托管资源。为确保您的记忆得到清理,只需确保在您使用完控件后没有任何内容引用它们。
您的问题不完整。但我可以回答其中 "how to avoid multiple instances" 部分的问题。要处理您的页面,您必须分离您的事件,将它们从 "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;
}
我为避免这种情况所做的是我有一个 window,里面有 2 个帧。我在每个帧中放置了每个源 XAML 之一,因此第 1 帧是 XAML 1,第 2 帧是 XAML 2。然后我只是将可见性编辑为折叠和可见。那么您没有任何页面更改或创建实例。您只需创建原始的 2 个实例。