【问题标题】:tabcontrol changing when user clicks on treeview node当用户单击树视图节点时选项卡控件发生变化
【发布时间】:2011-10-11 08:38:24
【问题描述】:

这是我的应用程序的概述:

它基本上是一本烹饪书。用户可以创建食谱,然后在该食谱中创建食谱。我有一个类 CookBook 和一个类食谱。 CookBook 跟踪与食谱相关的食谱,Recipe 跟踪食谱的内容。

对于 UI,我有一个树形视图,它将显示 CookBook 中的食谱。我有一个 TabControl,它将显示与每个配方关联的选项卡。选项卡由用户在运行时动态创建。

当用户单击其中一个食谱时,我希望 TabControl 显示与该特定食谱相关的选项卡。当用户单击不同的食谱时,我希望先前选择的选项卡消失,并出现当前选择的选项卡。 (旁注:稍后我会将选项卡的内容和内容保存到文件中,以供保存)

我希望 Recipe 类包含有关 TabControl 的详细信息(配方有多少选项卡、每个选项卡的标题、选项卡的内容)。但我不希望 Recipe 负责创建 Tabs 或 TabControl。

我的问题是,我如何完成上面的粗体部分?人们对这类问题有何看法和经验?解决此类问题的最佳做法是什么?

谢谢!

【问题讨论】:

    标签: c# visual-studio-2010 oop tabcontrol


    【解决方案1】:

    希望下面的代码能给你一个思路

    public Form1()
        {
            InitializeComponent();
    
            Recipe r1 = new Recipe() { Text = "Re1" };
            Recipe r2 = new Recipe() { Text = "Re2" };
            Recipe r3 = new Recipe() { Text = "Re3" };
    
    
            listBox1.Items.Add(r1);
            listBox1.Items.Add(r2);
            listBox1.Items.Add(r3);
    
    
            tabControl1.TabPages.Add(new AdvancedTabPage() { Recipe = r1,Text=r1.ToString() });
            tabControl1.TabPages.Add(new AdvancedTabPage() { Recipe = r2, Text = r2.ToString() });
            tabControl1.TabPages.Add(new AdvancedTabPage() { Recipe = r3, Text = r3.ToString() });
    
            listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged);
    
        }
    
        void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox1.SelectedItem != null)
                foreach (AdvancedTabPage ad in tabControl1.TabPages)
                {
                    if (ad.Recipe == listBox1.SelectedItem)
                    {
                        tabControl1.SelectedTab = ad;
                        break;
                    }
                }
    
        }
    
        public class AdvancedTabPage : System.Windows.Forms.TabPage
        {
            public Recipe Recipe{get;set;}
    
    
        }
    
        public class Recipe
        {
            public string Text = "";
    
            public override string ToString()
            {
                return Text;
            }
        }
    

    【讨论】:

    • AdvancedTabPage 类的用途是什么?那是我用来定义与食谱相关的标签的外观吗?如果是这样的话,“公共食谱食谱”的目的是什么……这对我来说没有意义。
    • Welcome,AdvancedTabPage 类继承了 TabPage,我在其中添加了一个名为 Recipe 的附加字段,它表示相关的配方 想法是在具有所需配方的选项卡中搜索
    • 非常有帮助,谢谢! =) 希望我可以选择两个问题作为答案。
    【解决方案2】:

    我认为这是一个 WinForms 应用程序?您遇到了经典的 UI 关注点分离问题。大多数开发人员(干净地)解决这个问题的方法是实现文档/视图模型之类的东西。多亏了 MFC,这是一个加载的术语,但仍然很有用。

    基本上,您的 Recipe 类就是文档。选项卡是视图。创建一个类来处理在选项卡(或任何其他 UI 容器)中显示配方的任务,并使用它来处理与用户的交互。视图通常与“容器”(在这种情况下是表单本身)紧密耦合,尽管它也可以被抽象出来。

    D/V 最基本的形式与MVC 模式非常相似,但如果您的应用程序足够简单,您可以取消控制器部分。 Here 是关于这个主题的一些简单的阅读。不要担心它指的是MFC,无论如何方法都是一样的。有关 MVC 的文档可能也很有用,但它往往侧重于基于 Web 的应用程序。

    有趣的东西:)

    【讨论】:

    • 我已经阅读了您讨论的内容,我真的很喜欢这个想法,这就是我想做的事情。但是,您能否解释一下这与 mohammed asaad 的建议相比有何不同?似乎 mohammed asaad 的建议不包含控制器。你能详细说明和/或比较吗?谢谢
    • 非常有帮助,谢谢! =) 希望我可以选择两个问题作为答案。
    【解决方案3】:

    我解决这个问题的一种方法是让每个 Treeview 的项目都引用它所代表的 Recipe 类。 Treeview 将触发在表单上捕获的选择更改事件,您可以在其中提取 Recipe 实例。然后这会将Recipe 实例传递给TabControl,TabControl 将根据Recipe 信息进行自我配置。

    要实现这一点,我可能会使用 MyTreeview.DisplayCookBook(CookBook book) 和 MyTabControl.DisplayRecipe(Recipe recipe) 等方法从 Treeview 和 TabControl 派生一个自定义类。这会将功能封装在它们各自的容器中,并通过事件相互通信,避免使用包含 1000 行代码的表单。

    希望能给你一些方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多