Error when binding using markup extensions: Unknown property encountered while parsing a Markup Extension
Asked Answered
D

3

9

In principle, I developed a neat way to bind RadioButtons to almost anything:

/// <summary>Converts an value to 'true' if it matches the 'To' property.</summary>
/// <example>
/// <RadioButton IsChecked="{Binding VersionString, Converter={local:TrueWhenEqual To='1.0'}}"/>
/// </example>
public class TrueWhenEqual : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object To { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return object.Equals(value, To);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((bool)value) return To;
        throw new NotSupportedException();
    }
}

For example, you can use this to bind RadioButtons to a string property as follows (it is a well-known bug that you must use a unique GroupName for each RadioButton):

<RadioButton GroupName="G1" Content="Cat"
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='CAT'}}"/>
<RadioButton GroupName="G2" Content="Dog"
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='DOG'}}"/>
<RadioButton GroupName="G3" Content="Horse"
    IsChecked="{Binding Animal, Converter={local:TrueWhenEqual To='HORSE'}}"/>

Now, I would like to use public static readonly objects called Filter1 and Filter2 as the values of my RadioButtons. So I tried:

<RadioButton GroupName="F1" Content="Filter Number One"
    IsChecked="{Binding Filter, Converter={local:TrueWhenEqual To='{x:Static local:ViewModelClass.Filter1}'}}"/>
<RadioButton GroupName="F2" Content="Filter Number Two"
    IsChecked="{Binding Filter, Converter={local:TrueWhenEqual To='{x:Static local:ViewModelClass.Filter2}'}}"/>

But this gives me an error:

Unknown property 'To' for type 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension' encountered while parsing a Markup Extension.

The error still occurs if I remove the quotes. What am I doing wrong?

Dinadinah answered 2/8, 2012 at 20:30 Comment(0)
F
9

It's a bug that can occur with nested MarkupExtensions. Try putting your custom Markup into a separate DLL/Project or use property element syntax.

Fattish answered 2/8, 2012 at 20:50 Comment(1)
The second link has the correct answer (by which I mean, the easy answer). I simply have to define a constructor public TrueWhenEqual(object to) { To = to; } and then invoke the converter with Converter={local:TrueWhenEqual {x:Static local:ViewModelClass.Filter1}}}Dinadinah
H
6

WPF doesn't handle nested markup extensions too well. To overcome this, you can use your markup extension as an element. It's a bit clumsy and harder to read, but it works:

<RadioButton GroupName="F1" Content="Filter Number One">
    <RadioButton.IsChecked>
        <Binding Path="Filter">
            <Binding.Converter>
                <local:TrueWhenEqual To={x:Static local:ViewModelClass.Filter1} />
            </Binding.Converter>
        </Binding>
    </RadioButton.IsChecked>
</RadioButton>

Another way would be to declare your converter and use it as a static resource:

<Window.Resources>
    <local:TrueWhenEqual To={x:Static local:ViewModelClass.Filter1} x:Key="myConverter" />
</Window.Resources>

<RadioButton GroupName="F1" Content="Filter Number One"
             IsChecked="{Binding Filter, Converter={StaticResource myConverter}}" />
Holmes answered 2/8, 2012 at 21:4 Comment(2)
Clunky, but it works. Well actually it doesn't work, but it does compile (I suspect the next problem is in my MVVM framework, UpdateControls).Dinadinah
Confirmed, this solution works without my MVVM framework. Defining a constructor on the MarkupExtension is a much better solution, though. Then I renamed it to TrueWhenEqualTo which reads more naturally: IsChecked="{Binding Filter, Converter={local:TrueWhenEqualTo {x:Static local:ViewModelClass.Filter1}}}". Of course, "naturally" is a relative term; XAML still looks like gibberish to the uninitiated ;^)Dinadinah
X
0

I encountered the same bug on a machine with .NET 4.6 installed. As soon as I updated to the .NET 4.7 (Developer Pack) this error gone without any code changes.

Xylograph answered 13/6, 2019 at 11:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.