我目前正在研究WPF上的CustomConverter
。这就像一个通用的转换。
阅读blog,找到了简化xaml的方法。
所以转换器看起来像这样:
public CustomConverter : MarkupExtension, IMultiValueConverter {
public ParametersCollection Parameters { get; set; }
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
if(Parameters == null)
return Binding.DoNothing;
//Convertion Logic
//...
}
public override object ProvideValue(IServiceProvider serviceProvider) {
return new CustomConverter();
}
}
public class ParametersCollection : ObservableCollection<object> {
}
在我的Xaml文件中,有以下内容:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primitives="clr-namespace:System;assembly=mscorlib"
xmlns:converter="clr-namespace:NS.Converters">
<Label>
<Label.Visibility>
<MultiBinding>
<converter:CustomConverter>
<converter:CustomConverter.Parameters>
<converter:ParametersCollection>
<primitives:String>Param1</primitives:String>
...
</converter:ParametersCollection>
</converter:CustomConverter.Parameters>
</converter:CustomConverter>
</MultiBinding>
<!--Bindings start here -->
</Label.Visibility>
</Label>
</UserControl>
因此,在对代码进行debbuging时,Parameters
属性为空(null),因此xaml不会填充集合。所以我的问题是,如何仅使用xaml而不是C#代码来推广参数。
答案 0 :(得分:0)
如果您在Convert
方法的第一行放置断点,则会发现Parameters
始终为null
。那是因为你永远不会初始化它。解决方案是在构造函数中初始化该属性(如果您在C#6中,则在声明中右侧)。
Parameters
不需要ObservableCollection<T>
,因为没有人会绑定它,也不需要是非通用的子类。最后,ProvideValue()
应该提供从XAML获得Parameters
的实际实例。如果您返回包含空Parameters
个集合的新实例,则该实例将不会有任何Parameters
。在创建和初始化后调用ProvideValue()
。目的不是为您自己的类提供新实例,而是为StaticResource
或DynamicResource
等标记扩展提供参数,并使用它们来创建或检索除自身以外的其他实例。
public class CustomConverter : MarkupExtension, IMultiValueConverter
{
public CustomConverter()
{
Parameters = new List<Object>();
}
public List<Object> Parameters { get; set; }
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (Parameters == null)
return Binding.DoNothing;
// Just something that returns something, for testing
// Replace with your own convertion logic.
return String.Join(";", Parameters);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}