locked
Why do i get this error (event called twice) RRS feed

  • Question

  • I have a "UserControl_Loaded" event when of course the UC loads.
    Its suppose to go and get all the files from the Video Library.

    I attached an image here to make it more clear....

    What happens is that the event is called and then goes to the line where the "GetFilesAsync()" is called.
    When that is called for the first time, it goes back to the beginning of the event (as if the event was called for a second time) then executes the rest of the code within the block.

    The thing is that i get the number of files within the Video Library doubled! meaning if i had 3 videos in my folder, i get a list of 6 files, Because the function is called twice!

    In the image, you can see that i am in debugging mode and i have a counter called "repeat" that is defined globally (int repeat = 0;) And repeat increments everytime the UC_Loaded event is called.(i.e. at the beginning of the event).

    After each execution line, i print the amount of times this event has been called. After each execution line, i change the end of the "Repeated" output string with a different letter "X,Y, and Z" to show you where exactly the error occurs.

    http://i53.tinypic.com/15cf5g8.jpg


    • Edited by ICode. _ Sunday, September 25, 2011 9:04 PM
    Sunday, September 25, 2011 9:00 PM

Answers

  • i solved the problem.

    solution:

    this is the second page in the application.

    the code in the first page that takes me to the second page was as follows:

    >>> Windows.Content = new Video();

    But when i wrote

    >>> Windows.Content = null;

    >>> Windows.Content = new Video();

    It didn't loop twice!

    Can anyone explain why exactly that happened? and if using null is an efficient way of fixing the problem?

    thanks

    Monday, September 26, 2011 7:32 PM

All replies

  • It looks like that UserControl_Loaded has been called twice. Could you double check to make sure UserControl_Loaded is used only once? Since GetFilesAsync() is an async operation, the second call to UserControl_Loaded can start before GetFileAsync() from the first call to UserControl_Loaded returns, which would cause what happens in your printscreen.
    Monday, September 26, 2011 9:17 AM
  • I checked twice before asking the question and now once again!!!...

    This is really weird!.

    this is where its called:

    <UserControl x:Class="Media8.Videos"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        d:DesignHeight="768" d:DesignWidth="1366" Loaded="UserControl_Loaded">

    And thats it!...no where else. 

    Monday, September 26, 2011 11:11 AM
  • The only thing I can think of is that repeat is a static variable in your usercontrol, and you have two instances of the UC in your main XAML....

    Can you post more code so we can try to reproduce it?


    Dennis Vroegop Destrato Microsoft MVP Surface Please mark an answer as "answered" if it does help you!
    Monday, September 26, 2011 12:19 PM
  • my "repeat" isn't static and UserControl isn't defined twice!

     

    The thing is...thats my code in this UC!

    all i have is a gridview and texblock.

    The rest of the code you can see im the image.

    I'll post it again just incase....

    -------C#---------

    public Videos()
            {
                InitializeComponent();
            }
            int repeat = 0;
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Window.Current.Content = new MainPage();
            }
    
            private async void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                repeat++;
                TextBo.Text += "\nRepeatedX: " + repeat.ToString() + "\n";
                try
                {
                    TextBo.Text += "\nRepeatedY: " + repeat.ToString() + "\n";
                    var folder = await Windows.Storage.KnownFolders.VideosLibrary.GetFilesAsync();
                    TextBo.Text += "\nRepeatedZ: " + repeat.ToString() + "\n";
                    int count = 0;
                    foreach (var file in folder)
                    {
                        TextBo.Text += file.FileName + "\n";
                        count++;
                    }
                    TextBo.Text += "Count: " + count.ToString() + "\n";
                    TextBo.Text += "\nRepeated: " + repeat.ToString() + "\n";
                }
                catch (Exception ex)
                { TextBo.Text = ex.Message; }
    
                
            }
    

    ---------XAML----------

    <UserControl x:Class="Application1.Videos"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="768" d:DesignWidth="1366" Loaded="UserControl_Loaded">
    
    <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="129*"/>
                <RowDefinition Height="51*"/>
                <RowDefinition Height="588*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="135*"/>
                <ColumnDefinition Width="1231*"/>
            </Grid.ColumnDefinitions>
            <Grid.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF0D0017"/>
                    <GradientStop Color="#FF340047" Offset="1"/>
                </LinearGradientBrush>
            </Grid.Background>
            <TextBlock Grid.Column="1" HorizontalAlignment="Left" Height="94" Margin="8,35,0,0" TextWrapping="Wrap" Text="Videos" VerticalAlignment="Top" Width="730"  FontSize="72" FontFamily="Segoe UI" FontWeight="Light"/>
            <Button Content="Button" HorizontalAlignment="Left" Height="Auto" Margin="48,70,0,0" VerticalAlignment="Top" Width="Auto" Style="{StaticResource BackButtonStyle}" Click="Button_Click"/>
            <GridView Grid.Column="1" HorizontalAlignment="Left" Height="457" Margin="0,8,0,0" Grid.Row="2" VerticalAlignment="Top" Width="1223">
    
    </GridView>
            <TextBlock FontSize="30" Name="TextBo" Grid.Column="1" HorizontalAlignment="Left" Height="504" Margin="153,0,0,0" Grid.Row="2" TextWrapping="Wrap" VerticalAlignment="Top" Width="624"/>
    
    
        </Grid>
    </UserControl>
    

    Thats my code! im still baffled

    Monday, September 26, 2011 4:44 PM
  • i solved the problem.

    solution:

    this is the second page in the application.

    the code in the first page that takes me to the second page was as follows:

    >>> Windows.Content = new Video();

    But when i wrote

    >>> Windows.Content = null;

    >>> Windows.Content = new Video();

    It didn't loop twice!

    Can anyone explain why exactly that happened? and if using null is an efficient way of fixing the problem?

    thanks

    Monday, September 26, 2011 7:32 PM
  • Another way is to add a boolean flag to ensure the UserControl_Loaded event is called only once per instance, like this

            bool loaded = false;

            private async void UserControl_Loaded(object sender, RoutedEventArgs e)

            {

                if (loaded)

                    return;

                loaded = true;

                // whatever code that should be here
            }

     

    You could take a look at this blog for reasons why Loaded events are sometimes invoked more than once:

    http://blogs.msdn.com/b/mikehillberg/archive/2006/09/19/loadedvsinitialized.aspx

    Monday, September 26, 2011 7:49 PM
  • But that code will still fail in my case.

    i don't know how to explain it very shortly....but in the middle of the code, my event "restarts" or gets called again. So 'loaded' could become true, and "// whatever code should be here" can be executing, but in the middle of it, it 'restarts'...and now because loaded is true, it'll stop the function with an incomplete executed code.

     

    Same thing (but opposite) goes if loaded = true is after the executed code.

     

    So that doesn't really change anything...

    i think i'll just stick to "Windows.Content = null;" for now.

    And thanks for your help and your link to the blog :)

    Monday, September 26, 2011 9:17 PM
  • With the snippet I mentioned, the first call to UserControl_Loaded will set "loaded" to true. So when UserControl_Loaded is called for the second time, it will return right away without executing anything else :)

    Either way, I am glad that you have the problem solved and thank you for raising the issue :)

    Monday, September 26, 2011 9:48 PM