使用标记扩展进行绑定时出错:解析标记扩展时遇到未知属性

Qwe*_*tie 9 data-binding wpf xaml radio-button

原则上,我开发了一种将RadioButtons绑定到几乎任何东西的简洁方法:

/// <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();
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,您可以使用它将RadioButtons绑定到字符串属性,如下所示(这是一个众所周知的错误,您必须为每个RadioButton使用唯一的GroupName):

<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'}}"/>
Run Code Online (Sandbox Code Playgroud)

现在,我想使用public static readonly被调用的对象Filter1Filter2我的RadioButtons的值.所以我尝试过:

<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}'}}"/>
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误:

解析标记扩展时遇到类型'MS.Internal.Markup.MarkupExtensionParser + UnknownMarkupExtension'的未知属性'To'.

如果我删除引号,则仍会出现错误.我究竟做错了什么?

Adi*_*ter 6

WPF不能很好地处理嵌套标记扩展.要解决此问题,您可以使用标记扩展作为元素.它有点笨拙,难以阅读,但它有效:

<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>
Run Code Online (Sandbox Code Playgroud)

另一种方法是声明转换器并将其用作静态资源:

<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}}" />
Run Code Online (Sandbox Code Playgroud)