barbarian
barbarian

Reputation: 1559

String array as comma separated string in XAML

How I can set value of string[] property in xaml?

I hava control with next property: string[] PropName

I want to set value of this property in next way:

<ns:SomeControl PropName="Val1,Val2" />

Upvotes: 8

Views: 5051

Answers (4)

Snowbear
Snowbear

Reputation: 17274

     <ns:SomeControl>
        <SomeControl.PropName>
            <x:Array Type="sys:String">
                <sys:String>Val1</sys:String>
                <sys:String>Val2</sys:String>
            </x:Array> 
        </SomeControl.PropName>
    </ns:SomeControl>

Upvotes: 3

Heinzi
Heinzi

Reputation: 172408

sll's answer is great, but you can avoid the resource if you want and write the value directly into the control:

<ns:SomeControl>
    <ns:SomeControl.PropName>
        <x:Array Type="sys:String" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 xmlns:sys="clr-namespace:System;assembly=mscorlib">  
            <sys:String>Val1</sys:String>  
            <sys:String>Val2</sys:String>  
        </x:Array>  
    </ns:SomeControl.PropName>
</ns:SomeControl> 

In addition, you can move the xmlns: declarations into the head element (Window, UserControl, etc.), so you don't clutter your control properties with it.

PS: If you are the one developing SomeControl, I'd use svick's approach and provide a TypeConverter.

Upvotes: 2

svick
svick

Reputation: 244968

You can use the <x:Array> markup extension, but its syntax is quite verbose.

Another option is to create your own TypeConverter that can convert from the comma-separated list to an array:

class ArrayTypeConverter : TypeConverter
{
    public override object ConvertFrom(
        ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string list = value as string;
        if (list != null)
            return list.Split(',');

        return base.ConvertFrom(context, culture, value);
    }

    public override bool CanConvertFrom(
        ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;

        return base.CanConvertFrom(context, sourceType);
    }
}

If the type you were converting to was your type, you could then apply the [TypeConverter] attribute to that type. But since you want to convert to string[], you can't do that. So you have to apply that attribute to all properties where you want to use this converter:

[TypeConverter(typeof(ArrayTypeConverter))]
public string[] PropName { get; set; }

Upvotes: 11

sll
sll

Reputation: 62544

The idea is to define custom values as Array in resources of a control/window and then just use Binding to a static resource:

<!-- or Window.Resources -->
<UserControl.Resources>
    <x:Array x:Key="CustomValues" 
             Type="sys:String"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
        <sys:String>Val1</sys:String> 
        <sys:String>Val2</sys:String> 
    </x:Array> 
</UserControl.Resources>

<!-- Then just bind -->
<ns:SomeControl PropName="{Binding Source={StaticResource CustomValues}}" />

Upvotes: 2

Related Questions