Declare a list of types in XAML

I use a value converter that needs to get a list of types, which is a property of the converter. If I were to use a list of double values, I could use the following syntax (which works as expected):

code

public class MyConverter : IValueConverter { public List<double> MyList { get; set; } // ... } 

Xaml

 <Converter:MyConverter x:Key="MyConverter"> <Converter:MyConverter.MyList> <System.Double>1</System.Double> <System.Double>2</System.Double> </Converter:MyConverter.MyList> </Converter:MyConverter> 

But if I try to use this approach with a list of types, an exception is thrown:

 Object of type 'System.RuntimeType' cannot be converted to type 'System.Collections.Generic.List`1[System.Type]' 

This is my converter and its use:

code

 public class MyConverter : IValueConverter { public List<Type> MyList { get; set; } // ... } 

Xaml

 <Converter:MyConverter x:Key="MyConverter"> <Converter:MyConverter.MyList> <x:Type TypeName="MyType1" /> <x:Type TypeName="MyType2" /> </Converter:MyConverter.MyList> </Converter:MyConverter> 

I assume that the XAML syntax is incorrect, but I cannot find the correct syntax.

+4
source share
2 answers

Sounds like a bug in the XAML designer. The code below worked for me. I can create and run the application. But in the R # designer, two lines with the System stand out : Type , and the designer crashes with the following two errors in the line:

Error 1 Type "Type" is not used as an element of an object, because it is not public or does not define an open constructor without parameters or type.
Error 2 Type Type does not support direct content. Therefore, when I tried this solution earlier (before giving the previous solution), I thought that I was doing something wrong. But the compiler still does not give any errors during assembly. In any case, what it looks like:

 <Window.Resources> <local:Holder x:Key="one"> <local:Holder.Types> <System:Type>System:Int32</System:Type> <System:Type>System:Double</System:Type> </local:Holder.Types> </local:Holder> </Window.Resources> <Grid > <ListBox DataContext="{StaticResource one}" ItemsSource="{Binding Path=Types, Converter={StaticResource one}}" /> </Grid> 

As far as you can see, the difference is in the declaration. You should use System.Type, not x: Type.

and the code as a sample

 using System; using System.Collections.Generic; using System.Globalization; using System.Windows.Data; using System.Linq; namespace stackProjects { public class Holder : IValueConverter { public List<Type> Types { get; set; } public Holder() { Types=new List<Type>(); } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return Types.Select(x => x.Name).ToList(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } } 

As I said, this is because the Type class is abstract. Hope this helps.

+2
source

Ok, the example below compiles and runs. I see that the calling converter and list are populated with 2 type objects. This is probably the best way to do this.


Here is the complete code I used:

 namespace WpfApplication4 { public class MyConverter : IValueConverter { public IList<Type> MyList { get; set; } public MyConverter() { MyList = new List<Type>(); } public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } public class MyType { public string Name { get; set; } public MyType() { } } } <Window x:Class="WpfApplication4.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication4" xmlns:runtime="clr-namespace:System.Runtime.InteropServices;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <sys:String x:Key="testdata">TestData</sys:String> <x:Array x:Key="listoftypes" Type="{x:Type sys:Type}"> <x:Type Type="local:MyType"/> <x:Type Type="local:MyType"/> </x:Array> <local:MyConverter x:Key="myconv" MyList="{StaticResource listoftypes}"/> </Window.Resources> <Grid> <TextBlock Text="{Binding Source={StaticResource testdata}, Converter={StaticResource myconv}}"/> </Grid> </Window> 
+1
source

All Articles