xaml上的ObservableCollection <t>

时间:2017-04-07 16:41:52

标签: c# wpf xaml markup-extensions imultivalueconverter

我目前正在研究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#代码来推广参数。

1 个答案:

答案 0 :(得分:0)

如果您在Convert方法的第一行放置断点,则会发现Parameters始终为null。那是因为你永远不会初始化它。解决方案是在构造函数中初始化该属性(如果您在C#6中,则在声明中右侧)。

Parameters不需要ObservableCollection<T>,因为没有人会绑定它,也不需要是非通用的子类。最后,ProvideValue()应该提供从XAML获得Parameters的实际实例。如果您返回包含空Parameters个集合的新实例,则该实例将不会有任何Parameters。在创建和初始化后调用ProvideValue()。目的不是为您自己的类提供新实例,而是为StaticResourceDynamicResource等标记扩展提供参数,并使用它们来创建或检索除自身以外的其他实例。

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;
    }
}