Skip to content

Markup extensions in EventSetter do not work #5353

@mikernet

Description

@mikernet
  • .NET Core Version: .NET 5
  • Windows version: 21H1 19043.1237
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: N/A - library only supports netcore3+

Problem description:

While attempting to make my Method Binding Extension work with EventSetter, it turned out that setting the Handler property to a markup extension does not appear to work. The markup extension is never instantiated (so ProvideValue() is not called). Instead, the following exception is thrown on InitializeComponent():

System.Windows.Markup.XamlParseException: ''XAML Node Stream: Missing EndMember for 'WpfApp2.MainWindow.System.Windows.FrameworkElement.Resources' before EndObject.' 

Sample code:

    <Window.Resources>
        <Style x:Key="ButtonStyle" TargetType="Button">
            <EventSetter Event="Click" Handler="{s:MethodBinding OnButtonClick}" />
        </Style>
    </Window.Resources>

The issue is 100% NOT the XAML structure.

Activity

changed the title [-]Markup extensions in EventSetter[/-] [+]Markup extensions in EventSetter do not work[/+] on Sep 20, 2021
vishalmsft

vishalmsft commented on Sep 21, 2021

@vishalmsft
Contributor

@mikernet Markup extension only works for Dependency Property. EventSetter.Handler is not a Dependency Property. Hence, this won't work.
Getting this working is a Feature Request.

added this to the Future milestone on Sep 21, 2021
mikernet

mikernet commented on Sep 21, 2021

@mikernet
Author

Oh, oops...that cryptic error message threw me off, didn't even think to check if it was a dependency property. A nicer error message here would be helpful, me thinks.

this-is-your-do

this-is-your-do commented on Sep 22, 2021

@this-is-your-do

@vishalmsft Thanks for taking a look, but there seems to be more going on here - I was able to successfully workaround this limitation by creating an empty derived class from EventSetter:
class EventSetter : System.Windows.EventSetter { }
And then simply using this derived class instead of the usual EventSetter in xaml:
<local:EventSetter Event="Click" Handler="{s:MethodBinding OnButtonClick}" />
Here, MethodBindingExtension is successfully called and I was able to get it (with some code changes) to return a working event handler as well.

Note, in particular, that this works despite Handler still not being a dependency property. Based on this and other evidence, I think markup extensions usually work just fine with regular properties. (Bindings don't, but not all markup extensions are bindings!)

Rather, it seems like there's something in xaml parsing that's special casing the EventSetter.Handler property in a way that prevents markup extensions from being used with it.

(Interestingly enough, if I were to change from EventSetter to local:EventSetter but not use an extension for the Handler property, things would break.)

mikernet

mikernet commented on Sep 22, 2021

@mikernet
Author

That makes more sense tbh...I could have sworn markup extensions worked for regular properties, but I've been out of WPF land for a few months so I'm a but rusty there, haha.

Just tested it and they do indeed work on normal properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mikernet@this-is-your-do@vishalmsft

        Issue actions

          Markup extensions in EventSetter do not work · Issue #5353 · dotnet/wpf