选项卡控件 class 具有 2 个通用类型的选项卡和页面,它们彼此 link
Tab control class with 2 generic types for tab and page that link to each other
我正在尝试为 UI API 提供基础 class 以提供 Tab 控件。它在 C#.NET (4.5) 中,但未使用 WinForms。
我的选项卡控件工作得很好,但要求在外观和功能上都有各种自定义选项卡和页面,而不是为每个选项卡和页面克隆大量代码,我试图提供一个通用基础 class,你给 TTab
和 TPage
类型。
想法在 API 然后我可以提供 classes,它只是将通用基础包装到非通用 class 中以实际使用:DefaultTabs : BaseTabs<DefaultTab, DefaultTabPage>
我没想到这会特别麻烦,但一路上我都弄糊涂了,我很确定我开始对这个问题视而不见了。
这是一个精简版:
namespace ExtendTabs.soExample
{
using System.Collections.Generic;
public class Example<TTab, TPage>
where TTab : Tab<TPage>, new()
where TPage : TabPage<TTab>, new()
{
private List<TTab> tabs;
public Example()
{
this.tabs = new List<TTab>();
this.tabs.Add(new TTab());
}
}
public class Tab<TPage>
where TPage : new() // where TPage : TabPage<..? All I can think of is "TabPage<Tab<TPage>>" and that seems very wrong.
{
public Tab()
{
this.Page = new TPage(); // Can't pass this in because of the where new() constraint.
//this.Page.Tab = this; // Can't do this because TPage does not contain where
//this.Page.Link(this); // Can't do this because TPage does not contain where
}
public TPage Page { get; private set; }
}
public class TabPage<TTab>
{
public TabPage() // Can't take in Tab<TPage> here because of type problems and new() constrain used.
{
}
public TTab Tab { get; internal set; }
internal void Link(TTab tab)
{
this.Tab = tab;
}
}
}
2个主要问题是:
它不会在主 class 行上编译,'TPage' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TPage' in the generic type or method 'ExtendTabs.soExample.Tab<TPage>'
。我不明白这个错误,因为 TPage 确实有一个 public 无参数构造函数并且是非抽象的。(感谢 Siva)
我似乎无法将 TTab
实例添加到 TPage
实例而不会以某种递归泛型类型结束。
我希望我已经关注这个问题太久了,并且试图让这个问题变得过于复杂。看起来它应该比这真的容易得多。有什么建议吗?
第一个问题源于主 class 不包括与子 class 相同的通用约束。根据 link Siva 提供的内容,我现在添加了 new()
约束并修复了该错误。
基于此SO Post,您可以将示例class更改为:
public class Example<TTab, TPage> // 'TPage' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TPage' in the generic type or method 'ExtendTabs.soExample.Tab<TPage>'
where TTab : Tab<TPage>, new()
where TPage : TabPage<TTab>, new() //new() is provided here as a means to indicate constraint
{
private List<TTab> tabs;
public Example()
{
this.tabs = new List<TTab>();
this.tabs.Add(new TTab());
}
}
我想我现在已经解决了这个问题:
namespace WindowsFormsApplication1.soExample
{
using System.Collections.Generic;
public abstract class BaseTabs<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
private List<TTab> tabs;
public BaseTabs()
{
this.tabs = new List<TTab>();
}
public IEnumerable<TPage> Pages
{
get
{
foreach (TTab tab in this.Tabs)
{
yield return tab.Page;
}
}
}
public IEnumerable<TTab> Tabs { get { return this.tabs; } }
public TTab Add()
{
TTab tab = new TTab();
this.tabs.Add(tab);
return tab;
}
}
public abstract class BaseTabsTab<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
public BaseTabsTab()
{
this.Page = new TPage();
this.Page.Tab = (TTab)this;
}
public TPage Page { get; private set; }
}
public abstract class BaseTabsTabPage<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
public BaseTabsTabPage()
{
}
public TTab Tab { get; internal set; }
}
public class DefaultTab : BaseTabsTab<DefaultTab, DefaultTabPage> { }
public class DefaultTabPage : BaseTabsTabPage<DefaultTab, DefaultTabPage> { }
public class DefaultTabs : BaseTabs<DefaultTab, DefaultTabPage> { }
}
这为选项卡和页面提供了强类型支持,双向支持,并允许创建具有扩展选项卡或页面的新选项卡。 3 个默认值 类 允许您使用它而不会卷入您不需要的肮脏的泛型减速:
DefaultTabs tabs = new DefaultTabs();
tabs.Add();
foreach (DefaultTab tab in tabs.Tabs) { }
foreach (DefaultTabPage page in tabs.Pages) { }
现在也应该清楚 link 从选项卡或页面返回主选项卡容器。
只是想我会 post 解决方案,以防其他人遇到类似的鸡和蛋仿制药问题。
我正在尝试为 UI API 提供基础 class 以提供 Tab 控件。它在 C#.NET (4.5) 中,但未使用 WinForms。
我的选项卡控件工作得很好,但要求在外观和功能上都有各种自定义选项卡和页面,而不是为每个选项卡和页面克隆大量代码,我试图提供一个通用基础 class,你给 TTab
和 TPage
类型。
想法在 API 然后我可以提供 classes,它只是将通用基础包装到非通用 class 中以实际使用:DefaultTabs : BaseTabs<DefaultTab, DefaultTabPage>
我没想到这会特别麻烦,但一路上我都弄糊涂了,我很确定我开始对这个问题视而不见了。
这是一个精简版:
namespace ExtendTabs.soExample
{
using System.Collections.Generic;
public class Example<TTab, TPage>
where TTab : Tab<TPage>, new()
where TPage : TabPage<TTab>, new()
{
private List<TTab> tabs;
public Example()
{
this.tabs = new List<TTab>();
this.tabs.Add(new TTab());
}
}
public class Tab<TPage>
where TPage : new() // where TPage : TabPage<..? All I can think of is "TabPage<Tab<TPage>>" and that seems very wrong.
{
public Tab()
{
this.Page = new TPage(); // Can't pass this in because of the where new() constraint.
//this.Page.Tab = this; // Can't do this because TPage does not contain where
//this.Page.Link(this); // Can't do this because TPage does not contain where
}
public TPage Page { get; private set; }
}
public class TabPage<TTab>
{
public TabPage() // Can't take in Tab<TPage> here because of type problems and new() constrain used.
{
}
public TTab Tab { get; internal set; }
internal void Link(TTab tab)
{
this.Tab = tab;
}
}
}
2个主要问题是:
它不会在主 class 行上编译,(感谢 Siva)'TPage' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TPage' in the generic type or method 'ExtendTabs.soExample.Tab<TPage>'
。我不明白这个错误,因为 TPage 确实有一个 public 无参数构造函数并且是非抽象的。我似乎无法将
TTab
实例添加到TPage
实例而不会以某种递归泛型类型结束。
我希望我已经关注这个问题太久了,并且试图让这个问题变得过于复杂。看起来它应该比这真的容易得多。有什么建议吗?
第一个问题源于主 class 不包括与子 class 相同的通用约束。根据 link Siva 提供的内容,我现在添加了 new()
约束并修复了该错误。
基于此SO Post,您可以将示例class更改为:
public class Example<TTab, TPage> // 'TPage' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TPage' in the generic type or method 'ExtendTabs.soExample.Tab<TPage>'
where TTab : Tab<TPage>, new()
where TPage : TabPage<TTab>, new() //new() is provided here as a means to indicate constraint
{
private List<TTab> tabs;
public Example()
{
this.tabs = new List<TTab>();
this.tabs.Add(new TTab());
}
}
我想我现在已经解决了这个问题:
namespace WindowsFormsApplication1.soExample
{
using System.Collections.Generic;
public abstract class BaseTabs<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
private List<TTab> tabs;
public BaseTabs()
{
this.tabs = new List<TTab>();
}
public IEnumerable<TPage> Pages
{
get
{
foreach (TTab tab in this.Tabs)
{
yield return tab.Page;
}
}
}
public IEnumerable<TTab> Tabs { get { return this.tabs; } }
public TTab Add()
{
TTab tab = new TTab();
this.tabs.Add(tab);
return tab;
}
}
public abstract class BaseTabsTab<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
public BaseTabsTab()
{
this.Page = new TPage();
this.Page.Tab = (TTab)this;
}
public TPage Page { get; private set; }
}
public abstract class BaseTabsTabPage<TTab, TPage>
where TTab : BaseTabsTab<TTab, TPage>, new()
where TPage : BaseTabsTabPage<TTab, TPage>, new()
{
public BaseTabsTabPage()
{
}
public TTab Tab { get; internal set; }
}
public class DefaultTab : BaseTabsTab<DefaultTab, DefaultTabPage> { }
public class DefaultTabPage : BaseTabsTabPage<DefaultTab, DefaultTabPage> { }
public class DefaultTabs : BaseTabs<DefaultTab, DefaultTabPage> { }
}
这为选项卡和页面提供了强类型支持,双向支持,并允许创建具有扩展选项卡或页面的新选项卡。 3 个默认值 类 允许您使用它而不会卷入您不需要的肮脏的泛型减速:
DefaultTabs tabs = new DefaultTabs();
tabs.Add();
foreach (DefaultTab tab in tabs.Tabs) { }
foreach (DefaultTabPage page in tabs.Pages) { }
现在也应该清楚 link 从选项卡或页面返回主选项卡容器。
只是想我会 post 解决方案,以防其他人遇到类似的鸡和蛋仿制药问题。