Hai
我有一个WPF用户控件,当我在另一个窗口中使用该控件时,它加载了两次,所以它为我抛出异常,因为它在usercontrol_loaded事件中有一些功能,当它加载两次抛出错误时,还有其他吗检查usercontrol是否像这样加载的方法,否则如何解决这个问题。
答案 0 :(得分:8)
如果你这样做,你不需要“firstLoadCalled”标志:
public MyControl()
{
this.Loaded += MyControl_Loaded;
}
private void MyControl_Loaded(object sender, RoutedEventArgs e)
{
this.Loaded -= MyControl_Loaded; //make it so MyControl_Loaded is only called once
/* code that runs once on first load */
}
答案 1 :(得分:7)
长话短说,请使用布尔标志:
private bool firstLoad = true;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (firstLoad)
{
firstLoad = false;
// Do somthing that want to do only once...
}
}
更长的故事: 显然,在WPF中,您不能假设加载的事件只被触发一次。
我在Tabitem中使用用户控件遇到了同样的情况。 每次通过选择激活Tabitem时,都会为此tabitem中的所有控件触发加载的事件。
干杯
答案 2 :(得分:5)
在给Zane的帖子写评论之后,我想到了一个想法:实际上你不想使用布尔标志这样的解决方案,或者你必须使它更加健壮。
原来,控制可能会被重新使用。这意味着,可以将控件添加到树中,然后删除,然后添加,然后删除等等。如果您确实需要过滤掉Loaded的多次调用,那么必须跟踪已卸载事件!
按照Zane的例子,它应该类似于以下代码:
using System.Windows;
using System.Windows.Controls;
public class LoadOnceUserControl : UserControl
{
private bool firstLoadCalled = false;
public LoadOnceUserControl()
{
this.Unloaded += (sender,e) => firstLoadCalled = false;
this.Loaded += (sender,e) =>
{
if (this.firstLoadCalled) return;
this.firstLoadCalled = true;
var copy = this.FirstLoaded;
if (copy != null) copy(sender,e);
});
}
/*public*/ event RoutedEventHandler FirstLoaded;
}
请注意,为了对称而添加类似的FirstUnloaded也是合理的。我从来没有看到它被称为虚假。 请注意,尽管我在评论Zane的时候写过 - 在这种方法中你不应该分离那些处理程序
答案 3 :(得分:0)
是的,我发现这种行为真的很奇怪。最终我认为Hertzel所说的是最好的方式 - 或者像这样推导出一个新的UserControl类:
你可以从LoadOnceUserControl派生东西,它的FirstLoaded事件只会被调用一次。
using System.Windows;
using System.Windows.Controls;
public class LoadOnceUserControl : UserControl
{
private bool firstLoadCalled = false;
public LoadOnceUserControl()
{
// Hook up our loaded event
this.Loaded += new RoutedEvent(delegate(object sender, RoutedEventArgs e)
{
// If FirstLoad hasn't been called and there are events to be called...
if (!this.firstLoadCalled && this.FirstLoaded != null)
{
this.FirstLoaded(sender, e);
}
// We've already called (or attempted to call) FirstLoad.
this.firstLoadCalled = true;
});
}
event RoutedEventHandler FirstLoaded;
}
答案 4 :(得分:-1)
/// <summary>
/// Interaction logic for HTMLViewer.xaml
/// <br/>
/// 20201208
/// </summary>
public partial class FoldersHistory : UserControl, ViewDocument_I, ViewNavigate_I
{
public FoldersHistory()
{
InitializeComponent();
//
Loaded += Control_Loaded;
Unloaded += Control_Unloaded;
}
private bool LOADED = false;
void Control_Loaded(object sender, RoutedEventArgs e)
{
if (LOADED)
return;
LOADED = true;
// *** DO YOUR PROCESS ***