原则上,我开发了一种将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();
}
}
例如,您可以使用它将RadioButton绑定到字符串属性,如下所示(众所周知,您必须为每个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'}}"/>
现在,我想使用名为Filter1
和Filter2
的public static readonly
对象作为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}'}}"/>
但这给了我一个错误:
类型的未知属性"To"'MS.Internal.MarkupExtensionParser+UnknownMarkupExtension'在分析标记扩展时遇到。
如果我删除引号,错误仍然会发生。我做错了什么?
这是嵌套MarkupExtensions可能出现的错误。请尝试将自定义标记放入单独的DLL/Project或使用属性元素语法。
-
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8427e852-0f4f-49b1-9810-28ef6f3bcf09/
-
http://webcache.googleusercontent.com/search?q=cache:viDdmFIGtq8J:www.hardcodet.net/2008/04/nested-标记扩展bug+&cd=1&hl=en&ct=clnk&gl=uk
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>
另一种方法是声明转换器并将其用作静态资源:
<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}}" />
我在安装了.NET 4.6的机器上遇到了同样的错误。我一更新到.NET 4.7(开发人员包),这个错误就消失了,没有任何代码更改。