One shot events using Lambda in C#

前端 未结 8 1637
無奈伤痛
無奈伤痛 2021-01-31 07:55

I find myself doing this sort of thing quite often:-

 EventHandler eh = null;  //can\'t assign lambda directly since it uses eh
 eh = (s, args) =>
 {
     //s         


        
8条回答
  •  天涯浪人
    2021-01-31 08:09

    Personally, I just create a specialized extension method for whatever type has the event I'm dealing with.

    Here's a basic version of something I am using right now:

    namespace MyLibrary
    {
        public static class FrameworkElementExtensions
        {
            public static void HandleWhenLoaded(this FrameworkElement el, RoutedEventHandler handler)
            {
                RoutedEventHandler wrapperHandler = null;
                wrapperHandler = delegate
                {
                    el.Loaded -= wrapperHandler;
    
                    handler(el, null);
                };
                el.Loaded += wrapperHandler;
            }
        }
    }
    

    The reason I think this is the best solution is because you often don't need to just handle the event one time. You also often need to check if the event has already passed... For instance, here is another version of the above extension method that uses an attached property to check if the element is already loaded, in which case it just calls the given handler right away:

    namespace MyLibraryOrApplication
    {
        public static class FrameworkElementExtensions
        {
            public static void HandleWhenLoaded(this FrameworkElement el, RoutedEventHandler handler)
            {
                if ((bool)el.GetValue(View.IsLoadedProperty))
                {
                    // el already loaded, call the handler now.
                    handler(el, null);
                    return;
                }
                // el not loaded yet. Attach a wrapper handler that can be removed upon execution.
                RoutedEventHandler wrapperHandler = null;
                wrapperHandler = delegate
                {
                    el.Loaded -= wrapperHandler;
                    el.SetValue(View.IsLoadedProperty, true);
    
                    handler(el, null);
                };
                el.Loaded += wrapperHandler;
            }
        }
    }
    

提交回复
热议问题