Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF User Control loading twice

Hai

am having a WPF user control, when i use that control in another window it loading twice, so its throwing exception for me, coz am having some function in usercontrol_loaded event, when it loading twice it throwing error, is there any other way to check if the usercontrol is loaded like that, else how to solve this issue.

like image 262
Spen D Avatar asked Mar 17 '10 08:03

Spen D


3 Answers

Long story short, use a boolean flag:

    private bool firstLoad = true;
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        if (firstLoad)
        {
            firstLoad = false;

            // Do somthing that want to do only once...
        }
    }

Longer story: Apparently, in WPF you can't assume the loaded event is fired only once.

I've encountered the same situation using a user control in a Tabitem. Every time you activate a Tabitem by selecting it the loaded event is fired for all controls within this tabitem.

Cheers

like image 114
Hertzel Guinness Avatar answered Oct 04 '22 21:10

Hertzel Guinness


You don't need a "firstLoadCalled" flag if you do it this way:

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 */
}
like image 27
FocusedWolf Avatar answered Oct 04 '22 21:10

FocusedWolf


After writing comment to Zane's post, a after thought came to me: actually you dont want to use such solution with boolean flag, or you must make it even more robust.

It cames to be, that a Control may be REUSED. This means, that the control may be added to tree, then removed, then added, then removed and so on. If you really need to filter out the multiple invocations of Loaded, you must track the Unloaded event, too!

Following Zane's example, it should resemble following code:

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;
}

Please note that it also could be reasonable to add analogous FirstUnloaded just for symmetry. I have never seen it called spuriously though. And mind that despite waht I wrote in comment to Zane's - in this approach you should not detach that handlers

like image 33
quetzalcoatl Avatar answered Oct 04 '22 20:10

quetzalcoatl