user1202434
user1202434

Reputation: 2273

How do i wrap a standard wpf event with an event of my own?

I have a user control that contains a ListBox.

I want to expose a SelectionChanged event on my user control that wraps the listBox.SelectionChanged event.

So that, when the listbox item selection changes, my own custom event on the user control also gets fired after that...

How would I do that? Any sample would be appreciated. Thanks!

Upvotes: 0

Views: 1242

Answers (2)

Dan Busha
Dan Busha

Reputation: 3803

If you want your custom event on your UserControl to bubble up the visual tree you should expose it as a RoutedEvent. In your .xaml.cs file you'll need to register the event as a routed event and then implement a custom handler and event args class.

XAML:

<UserControl x:Class="WpfApplication1.MyUserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
       <ListView Name="myListView" SelectionChanged="OnSelectionChanged_"/>
    </Grid>
</UserControl>

Code:

public partial class MyUserControl : UserControl
{
    public delegate void CustomSelectionChangedEventHandler(object sender, SelectionChangedRoutedEventArgs args);


    public static readonly RoutedEvent CustomSelectionChangedEvent = EventManager.RegisterRoutedEvent(
        "CustomSelectionChanged", RoutingStrategy.Bubble, typeof(CustomSelectionChangedEventHandler), typeof(MyUserControl));


    public event RoutedEventHandler CustomSelectionChanged
    {
        add { AddHandler(CustomSelectionChangedEvent, value); }
        remove { RemoveHandler(CustomSelectionChangedEvent, value); }
    }


    public MyUserControl()
    {
        InitializeComponent();
    }


    private void OnSelectionChanged_(object sender, SelectionChangedEventArgs e)
    {
        RaiseEvent(new SelectionChangedRoutedEventArgs(myListView, CustomSelectionChangedEvent, e.AddedItems, e.RemovedItems)); 
    }
}


public class SelectionChangedRoutedEventArgs : RoutedEventArgs
{
    public IList AddedItems { get; set; }
    public IList RemovedItems { get; set; }

    public SelectionChangedRoutedEventArgs(object source, RoutedEvent routedEvent, IList addedItems, IList removedItems) 
        : base(routedEvent, source)
    {
        AddedItems = addedItems;
        RemovedItems = removedItems;
    }
}

The caller of your control would then provide an event handler for the CustomSelectionChanged event with the signature of:

private void OnCustomSelectionChanged(object sender, SelectionChangedRoutedEventArgs e) { }

Upvotes: 1

Kal_Torak
Kal_Torak

Reputation: 2551

I'm not sure wrapping is the best approach, even if you could wrap it. I'd suggest just defining your own event, and fire your own event in the handler hooked to listBox.SelectionChanged. You can then pass on any data from the original listbox event to your own event.

Added sample:

public partial class MainWindow : Window
{
    public delegate void CustomSelectionChangedEventHandler(object sender, SelectionChangedEventArgs e);
    public event CustomSelectionChangedEventHandler CustomSelectionChanged;


    public MainWindow()
    {
        InitializeComponent();
        listBox1.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
        {
            OnCustomSelectionChanged(e);
        };

    }

    void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        OnCustomSelectionChanged(e);
    }

    //We'll use the system defined SelectionChangedEventArgs type instead of creating a derived EventArgs class
    protected virtual void OnCustomSelectionChanged(SelectionChangedEventArgs e)
    {
        if (CustomSelectionChanged != null)
            CustomSelectionChanged(this, e);

    }
}

Further reading:

Upvotes: 1

Related Questions