首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#通用用户控件WPF

C#通用用户控件WPF
EN

Stack Overflow用户
提问于 2011-03-15 18:45:46
回答 6查看 6.3K关注 0票数 9

我尝试构建一个用户控件来显示Dictionary的内容

问题是我不知道用户控件中键和值的类型,我在创建用户控件时就知道了,但C#似乎不想让我创建一个通用用户控件,让我将它们传递到托管字典中

代码语言:javascript
运行
复制
public class MyCtrl<TKey,TValue> : UserControl
{
    private Dictionary<TKey,TValue>
}

因为它引用了.\Obj\Debug\MyCtrl.g.i.cs中生成的只读文件

呈现给我的唯一解决方案是从头开始创建类,而不是让设计者处理任何格式。有没有更好的可能性?

为了在我的代码中给出大约8-10个地方的背景,我需要用户填充值的字典,而不是构建8-10个控件,它们都做着完全相同的事情,但类型不同(实际上,很多时候唯一的区别是哪个枚举用作键),我想要一个控件来处理这个问题

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-03-15 18:50:38

您可以像不使用XAML一样使用泛型。但是,如果要使用XAML定义控件,则不能使用泛型

票数 3
EN

Stack Overflow用户

发布于 2011-04-05 00:48:12

我终于有了一个有效的答案。

我围绕使用对象的Hashtable构建控件

然后向对象类添加扩展名

代码语言:javascript
运行
复制
    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);
        }
    }

然后添加一个泛型属性,该属性调用扩展以将对象强制转换为字典

票数 2
EN

Stack Overflow用户

发布于 2011-03-15 19:06:59

如果你想在xaml中使用你的控件,你就不能以这种方式创建一个通用的UserControl,因为WPF不支持它。如何在xaml中以声明方式实例化该类型?

我会看看其他控件如何处理类似的事情。例如,ListBox允许您填充项目列表,而无需考虑解析到其ItemsSource中的集合的类型。

代码语言:javascript
运行
复制
<ListBox ItemsSource="{Binding DictionaryItems}" >
   <ListBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Key}" />
            <TextBlock Text="{Binding Value}" />
         </StackPanel>
      </DataTemplate>
   </ListBox.ItemTemplate>
 </ListBox>

对于不同的字典类型,您可以为每个不同的字典类型使用多个DataTemplates,并使用一个TemplateSelector进行切换。

代码语言:javascript
运行
复制
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;
   }
}

然后在xaml中

代码语言:javascript
运行
复制
<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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5310555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档