Edward Tanguay
Edward Tanguay

Reputation: 193302

Why does this C# event handler not respond to this event?

The following code is a silverlight application but the same happens in WPF, so it seems to be just something I'm missing regarding the delegate, event, etc.

Can anyone tell me why the following code successfully executes this event:

OnLoadingComplete(this, null);

but never executes this event handler?

void initialDataLoader_OnLoadingComplete(object obj, DataLoaderArgs args)

CODE:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Diagnostics;

namespace TestEvent22928
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            DataLoader initialDataLoader = new DataLoader("initial");
            initialDataLoader.RegisterText("test1", "http://test:111/testdata/test1.txt");
            initialDataLoader.RegisterText("test2", "http://test:111/testdata/test2.txt");
            initialDataLoader.BeginLoading();
            initialDataLoader.OnLoadingComplete += new DataLoader.LoadingComplete(initialDataLoader_OnLoadingComplete);
        }

        void initialDataLoader_OnLoadingComplete(object obj, DataLoaderArgs args)
        {
            Debug.WriteLine("loading complete"); //WHY DOES EXECUTION NEVER GET HERE?
        }
    }


    public class DataManager
    {
        public DataLoader CreateDataloader(string dataloaderIdCode)
        {
            DataLoader dataLoader = new DataLoader(dataloaderIdCode);
            return dataLoader;
        }
    }

    public class DataLoader
    {
        public string IdCode { get; set; }
        public List<DataItem> DataItems { get; set; }

        public delegate void LoadingComplete(object obj, DataLoaderArgs args);
        public event LoadingComplete OnLoadingComplete = delegate { };

        private int dataItemCurrentlyLoadingIndex;

        public DataLoader(string idCode)
        {
            IdCode = idCode;
            DataItems = new List<DataItem>();
            dataItemCurrentlyLoadingIndex = -1;
        }

        public void RegisterText(string idCode, string absoluteSourceUrl)
        {
            DataItem dataItem = new DataItem
            {
                IdCode = idCode,
                AbsoluteSourceUrl = absoluteSourceUrl,
                Kind = DataItemKind.Text
            };
            DataItems.Add(dataItem);
        }

        public void BeginLoading()
        {
            LoadNext();
        }

        private void LoadNext()
        {
            dataItemCurrentlyLoadingIndex++;
            if (dataItemCurrentlyLoadingIndex < DataItems.Count())
            {
                DataItem dataItem = DataItems[dataItemCurrentlyLoadingIndex];
                Debug.WriteLine("loading " + dataItem.IdCode + "...");
                LoadNext();
            }
            else
            {
                OnLoadingComplete(this, null); //EXECUTION GETS HERE
            }
        }
    }

    public class DataItem
    {
        public string IdCode { get; set; }
        public string AbsoluteSourceUrl { get; set; }
        public DataItemKind Kind { get; set; }
        public object DataObject { get; set; }
    }

    public enum DataItemKind
    {
        Text,
        Image
    }

    public class DataLoaderArgs : EventArgs
    {
        public string Message { get; set; }
        public DataItem DataItem { get; set; }

        public DataLoaderArgs(string message, DataItem dataItem)
        {
            Message = message;
            DataItem = dataItem;
        }
    }
}

Upvotes: 0

Views: 609

Answers (1)

Dan Bryant
Dan Bryant

Reputation: 27495

You're registering the handler only after you start loading:

        initialDataLoader.BeginLoading();
        initialDataLoader.OnLoadingComplete += new DataLoader.LoadingComplete(initialDataLoader_OnLoadingComplete);

The way your code is currently written, it looks like BeginLoading() blocks until completion, which means the handler will never be called, as you don't set it until after you've finished loading.

Upvotes: 7

Related Questions