C# 选项卡控件类,具有两个用于彼此链接的选项卡和页面的泛型类型

C# 选项卡控件类,具有两个用于彼此链接的选项卡和页面的泛型类型,c#,.net,generics,C#,.net,Generics,我试图为UI API提供一个基类,以提供一个选项卡控件。它在C#NET(4.5)中,但不使用WinForms 我的tab控件工作得很好,但是出现了一个要求,即在外观和功能上都有各种定制的选项卡和页面,并且不是为每个选项卡和页面克隆大量代码,而是尝试提供一个通用的基类,您可以给它一个TTab和TPage类型 其思想是在API中,我可以提供一些类,这些类只需将泛型基类包装成一个非泛型类即可实际使用:DefaultTabs:BaseTabs 我没想到这会特别麻烦,但我一路上都弄糊涂了,我很确定我开始对

我试图为UI API提供一个基类,以提供一个选项卡控件。它在C#NET(4.5)中,但不使用WinForms

我的tab控件工作得很好,但是出现了一个要求,即在外观和功能上都有各种定制的选项卡和页面,并且不是为每个选项卡和页面克隆大量代码,而是尝试提供一个通用的基类,您可以给它一个
TTab
TPage
类型

其思想是在API中,我可以提供一些类,这些类只需将泛型基类包装成一个非泛型类即可实际使用:
DefaultTabs:BaseTabs

我没想到这会特别麻烦,但我一路上都弄糊涂了,我很确定我开始对这个问题视而不见了

下面是一个简单的版本:

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;
        }
    }
}
namespace ExtendTabs.soe示例
{
使用System.Collections.Generic;
公开课范例
其中TTab:Tab,new()
其中TPage:TabPage,new()
{
私有列表选项卡;
公共示例()
{
this.tabs=新列表();
this.tabs.Add(new TTab());
}
}
公共类选项卡
where-TPage:new()//where-TPage:TabPage基于此,您可以将示例类更改为:

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());
        }
    }
公共类示例//“TPage”必须是具有公共无参数构造函数的非抽象类型,才能在泛型类型或方法“ExtendTabs.soExample.Tab”中将其用作参数“TPage”
其中TTab:Tab,new()
此处提供了TPage:TabPage,new()//new()作为指示约束的方法
{
私有列表选项卡;
公共示例()
{
this.tabs=新列表();
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> { }
}
现在也应该清楚地从选项卡或页面链接回主选项卡容器


我想我会发布解决方案,以防其他人遇到类似的鸡和蛋类仿制药问题。

应该会帮助你。确实如此,非常感谢。现在编辑问题。所以,层次结构是一个选项卡控件,它会有选项卡,而选项卡又会有选项卡页?对吗?没错,是的-理想情况下,我希望有一个获取的方法页面的枚举一直到主选项卡控件,但一旦链接起作用,我确信我可以使用自定义迭代器对其进行排序。主要的是我需要能够从TTab获取TPage,从TPage获取TTab,因为它用于各种不同的事情。理想情况下,我希望能够从bo获取tab容器也一样,但一次只做一件事!太好了,谢谢。这修复了第一个错误-我编辑了问题以反映。
DefaultTabs tabs = new DefaultTabs();
tabs.Add();
foreach (DefaultTab tab in tabs.Tabs) { }
foreach (DefaultTabPage page in tabs.Pages) { }