C # Generic User Control WPF

I am trying to create a user control that displays the contents of a dictionary

the problem is that I don’t know the types for the key and value in the User control, I would know that I am creating a user control, but C # does not seem to want me to create a common user control that will allow me to pass them to hosted dictionary

t

public class MyCtrl<TKey,TValue> : UserControl { private Dictionary<TKey,TValue> } 

since it refers to the generated file in. \ Obj \ Debug \ MyCtrl.gics which is read only

The only solution that presents itself to me is to create a class from scratch and not allow the constructor to handle any formatting, is there a better opportunity?

to give a little background in about 8-10 places in my code, I need the user to fill in dictionaries of values ​​and instead of creating 8-10 controls that all do exactly the same, but with different types (actually a lot of time, the only difference is which enumeration serves as the key), I wanted one control to handle this

+7
source share
6 answers

You can use generic as if you were not using XAML. But if you want to use XAML to define your control, you cannot use generic

+3
source

I finally have a working answer.

I create a control around a hashtable that uses objects

then add the extension to the feature class

  public static bool TryParse<TType>(this object obj, out TType result) { try { result = (TType)Convert.ChangeType(obj, typeof(TType)); return true; } catch { result = default(TType); return false; } } public static TType Parse<TType>(this object obj) where TType : struct { try { return (TType)Convert.ChangeType(obj, typeof(TType)); } catch { throw new InvalidCastException("Cant cast object to " + typeof(TType).Name); } } 

then add a common property that causes the extension to pass objects to the dictionary

+2
source

If you want to use your control in xaml, you cannot create a generic UserControl in this way, since WPF just does not support it. How do you declaratively instantiate this type in xaml?

I would see how other controls will handle something like this. For example, a ListBox allows you to populate a list of items without any relation to the type of collection parsed in its ItemsSource.

 <ListBox ItemsSource="{Binding DictionaryItems}" > <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Key}" /> <TextBlock Text="{Binding Value}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> 

For different types of dictionaries, you can have several DataTemplates for each type of dictionary and switch using TemplateSelector.

 public class SomeSelector : DataTemplateSelector { public DataTemplate Template1 { get; set; } public DataTemplate Template2 { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item is IDictionary<string, int>) { return Template1; } return Template2; } } 

Then in xaml

 <UserControl.Resources> <DataTemplate x:Key="Template1"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Key}" /> <TextBlock Text="{Binding Value}" /> </StackPanel> </DataTemplate> <DataTemplate x:Key="Template2> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Key}" /> <TextBlock Text="{Binding Value}" /> </StackPanel> </DataTemplate> <SomeSelector x:Key="SomeSelector" Template1="{StaticResource Template1}" Template2="{StaticResource Template2}" /> </UserControl.Resources> <ListBox ItemsSource="{Binding DictionaryItems}" ItemTemplateSelector="{StaticResource SomeSelector}" /> 
+1
source

As Steyca mentioned, you cannot use generics in XAML. However, you can create your own common user control and get certain types from this common class that you can use in XAML. This at least reduces code duplication to some extent.

As a side element, generic elements in XAML may be possible if you yourself support it by passing Type as the value of the property. At least I believe that the goal is in this article , but I did not have time to try it myself.

+1
source

You might be better off using MVVM and putting all of the common types and constraints in your view model rather than your view.

+1
source

The reason you want to install a common user control is because you don't know which key and value:

  private Dictionary<TKey,TValue> someDictionary; 

types will be in advance, I believe. If so, declare your dictionary as:

 private Dictionary<dynamic,dynamic> someDictionary 

then you can add any type of key and value to it. so make sure that if the key is int and your values, for example, a string, then this template always follows. For example, the compiler allows you to compile this code:

  Dictionary<dynamic, dynamic> myDictionAry = new Dictionary<dynamic, dynamic>(); myDictionAry.Add(1, "kd"); myDictionAry.Add("kjdf", 3); 
0
source

All Articles