【问题标题】:WPF custom control with generics - possible?带有泛型的 WPF 自定义控件 - 可能吗?
【发布时间】:2011-10-25 00:55:07
【问题描述】:

我想使用泛型创建一个自定义 WPF 控件:

public class MyGenericTypeControl<T> : ItemsControl 
{   
   // ...
}

这可能吗?在我最初的实验中,一旦我尝试在某处添加此控件,就会出现设计时/编译时 XAML 错误。这并不奇怪,因为构建我的自定义控件需要 XAML 不提供的其他信息。

有什么想法吗?

【问题讨论】:

    标签: c# wpf generics xaml controls


    【解决方案1】:

    XAML 不支持泛型,您需要创建一个空的非泛型类,该类继承自您的泛型控件并将其与您的XAML 一起使用

    【讨论】:

    • 我希望我的控件不知道正在使用的特定泛型类型。使用这种方法,非泛型派生类需要告诉基类泛型类型是什么,我不想这样做。
    • 抱歉,唯一的解决方案是创建一个包含所有重要代码的通用控件,然后使用不同类型参数从它继承的一堆空类
    • @kindohm 已经说得够多了,这是不可能的,但我想指出,这样做的理由并不多。你为什么需要那个?您已经可以在 WPF 中进行大量修改。 DataTemplates 具有很大的灵活性,使用 DataTemplateSelector 和触发更改模板,您可以创建几乎所有您想要的东西。为什么需要使用泛型参数的控件?为什么不是接口?如果您提供更多代码,我们可能会为您提供更好的选择。
    • @DeanChalk - “XAML 不支持泛型” 不完全正确。 WPF 在 PageFunction 中支持泛型。 msdn.microsoft.com/en-us/library/ms615540(v=vs.110).aspx
    【解决方案2】:

    使用x:TypeArguments的支持有限

    对于 XAML 2006 的使用,以及用于 WPF 应用程序的 XAML,对于 x:TypeArguments 和来自 XAML 的泛型类型使用通常存在以下限制:

    • 只有 XAML 文件的根元素可以支持引用泛型类型的泛型 XAML 用法。
    • 根元素必须映射到具有至少一个类型参数的泛型类型。一个例子是PageFunction&lt;T&gt;。页面函数是 WPF 中 XAML 泛型使用支持的主要场景。
    • 泛型的根元素 XAML 对象元素还必须使用 x:Class 声明分部类。即使定义 WPF 构建操作也是如此。
    • x:TypeArguments 不能引用嵌套的泛型约束。

    【讨论】:

      【解决方案3】:

      您只能以相反的方式执行此操作(从通用基类继承的非通用控件):

      public class BaseControl<T> : Control
      {
         // base implementation
      }
      
      
      public class MyControl : BaseControl<string>
      {
         // ...
      }
      

      MyConrtrol 的 XAML 如下所示:

      <local:MyControl x:Class="BaseControl"
                       x:TypeArguments="sys:String"
                       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:local="clr-namespace:MyNamespace"
                       xmlns:sys="clr-namespace:System;assembly=System.Runtime">
          ....
      <local:MyControl/>
      

      请注意属性x:TypeArguments="....."。如果您的类型参数本身是通用的,那么您可以使用例如以下:

      <local:MyControl x:Class="BaseControl"
                       x:TypeArguments="sys:Tuple(sys:String,sys:Int32)"
                       ...>
      

      代码相当于:

      public class MyControl : BaseControl<Tuple<string, int>>
      {
         // ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多