How does one hook custom events into Xaml?

I'm trying to implement a Data Binding layer to protect my UI from business logic dependencies.

I'm using XAML to bind a control (TextBox in this case) to a datasource, which works just fine so far.

However, the underlying datasource fires a custom event. The UI needs to catch this event and act on it (enable some controls). If I use code behind to register for the event and catch it, then I'm breaking the markup/code separation.

How can I register for and catch a custom event strictly in XAML code

Note1: Just to make it intgeresting, the event is a generic that derives from AsyncCompletedEventArgs

Note2: The event will be coming in on a separate thread. I don't suppose there is any infrastructure in place to take care of dispatching an Invoke for UI operations on secondary threads

Thanks

NIK

 

 

 




Answer this question

How does one hook custom events into Xaml?

  • Ashton

    What is your particular requirement on a routed event Is it going to be handled on a different XAML element than it will be raised by Or are you just getting steered that way by the EventTrigger angle

    To be a RoutedEvent, you need to be registered as a RoutedEvent. So if the event you are using is an already existant event, that very event can't be a RoutedEvent; you'd need for forward it. But that's not the end of the difficulty. In order to raise a RoutedEvent (or at least to be reported as the source for a RoutedEvent) you need to be a UIElement subclass; that's the point where the RaiseEvent method is defined.

    Does your change-reporting mechanism have to be that event All you really need is a property that changes. You could then one-way bind that property to something (ideally a FrameworkElement that is already the recipient of whatever other data you're binding) and use the FE.SourceUpdated event handling to detect changes. It's a little bit of a hack, but you could for instance bind your data flag to the FE.Tag property so that your property is participating in a binding yet not messing with any "real" property value, and make sure the property flops in some way every time you want to "raise the event". Using Tag that way will possibly save you a subclass just to add a property that's not really a full part of your object model anyways. Data binding is already asynch, so I don't think your threading issue will be in play.


  • Nicolas Webb

    Ok, I have a slightly better understanding of things now. I kinda see where you are going with that.

    My basic requirement is that my UI guy be able to write Xaml that will listen for an event at the "form" level and be able to take action on it. It doesn't necessarily have to be attached to a specific control or its data binding, but that might be the mechanism. Again, it doesn't have to be a routed event unless that is the only type I can reference/access in XAML.

    In general terms, I just need some way to express in XAML "when this thing happens, then do this".

    For Example: Setting this particular property takes 3-7 seconds to complete in the physical world. We might want to disable some UI elements while its working, then re-enable them when its done.

    Thanks again for thinking this through with me and not just dropping in a doc link and running.

    NIK

    PS. After a few days with this framework, its still hard for me to think beyond the old event-driven paradigm.



  • homez99

    Ok, so I'll handle the custom event and send a RoutedEvent on to the page/window.

    What about the threading issue

    The event I am picking up always comes in on a separate pooled thread. Will .NET take care of the details or do I have to somehow get back on the UI thread before I fire the event

    NIK



  • Krazon

    Should have save that for another thread, but OK, I'll have to use a Dispatcher (documented and doable).

    Back to the custom event problem:

    I reviewed the EventTrigger and RoutedEvent stuff and it still not clear to me how I can simply fire an event from my DataSource and have it picked up on the XAML page.

    ms-help://MS.MSSDK.1033/MS.WinFXSDK.1033/wpf_conceptual/html/b79f459a-1c3f-4045-b2d4-1659cc8eaa3c.htm

    IMHO, the sample materials don't really explain how to create a custom routed event. The Custom Routed Event sample just shows you how to sub-class a button, override its Click event and catch the event via a different name "Tag" in XAML.

    What I need to do is create an object (not just sub-class an existing UI control) that can raise a RoutedEvent and that I can reference in XAML to catch the event. Again, this thing needs to pick up events from my DataSource layer, then pass on a Routed Event to other elements of the XAML page somehow.

    I tried stripping down the Custom Routed Event sample, but it relies on button for a lot of required functionality (AddHandler, RemoveHandler, Name property, etc.)

    Different Angle - What about the DataSource

    Is there perhaps a mechanism therein that I can trigger behavior on the form. The event is the result of activity within the DataSource, I don't have to express it to the XAML pages as an event, I just have to catch it in my data layer as an event.

    Thanks for your patience

    NIK



  • salim_555

    A lot has changed in my implementation since this post. I wound up implementing my own binding/glue layer between the XAMl binding and my business objects. I do most of my plumbing there.

    Property setters are pretty useful as long as you don't need to access other controls.

    I'd be happy to help if I can, although your best bet is to describe it in a separate post so that you can pick up the collective wisdom of the forum. Link it in here so that I get an alert.

    Thanks



  • SMOwais

    Everything that derives from DispatcherObject (which is most everything in the WPF UI class hierarchies) has a Dispatcher property. Call the BeginInvoke method on that object to marshal a call back to the UI thread.

    Josh



  • TonMekking

    hi nicknotyet,

    did you find a solution for your problem. i'm trying to solve a similar problem, but i couldn't find a solution so far. Any hints

    Thanks,
    bkohler

  • Interdit

    Look in the docs on EventTrigger. You can attach the trigger to most elements or styles. The event must be a type of RoutedEvent to be used in XAML. This has restricted the types of mouse events that can be used directly in XAML since some of them are not RoutedEvents. You can always listen for one event in code and raise a RountedEvent for XAML use.

  • How does one hook custom events into Xaml?