【问题标题】:Moving controls from TabPage to Panel; controls being skipped将控件从 TabPage 移动到 Panel;被跳过的控件
【发布时间】:2015-06-07 13:49:27
【问题描述】:

所以每个人都知道现在显示设置的一种非常流行的方法是在左侧有一个 ListView,并在单击时更改右侧的面板。

几年前,我遇到了一种轻松管理它的方法是创建一个 TabControl,在设计时将每个设置类别的控件放在标签页中,因为它可以轻松切换标签和编辑页面。

在运行时,当打开设置页面时,为每个TabPage创建Panels,将控件从TabPage移动到其对应的panel,并将每个TabPage的Text(标题)添加到左侧的ListView中。然后,如果需要,您可以销毁 TabControl 以释放内存。

我遇到的问题是,当我的代码遍历 TabPage 上的控件时,它不会添加其中的一些。就我而言,它们目前都是 CheckBoxes,所以我很困惑为什么有些不会被移动。在调试期间,我可以检查 TabPage.Controls 并且所有 CheckBox 都在那里,但是随着它的迭代,它只是没有将一些控件添加到面板中。

我对在 DesignTime 期间如何进行此设置、在 RunTime 中的外观以及处理从 TabPages 到 Panels 的移动的代码有一个图像。

有没有人知道为什么会发生这种情况?我被难住了。

设计时间:http://postimg.org/image/h6ssw1chp/

运行时间:http://postimg.org/image/4i7f6uv05/

public void setPanels()
{
    foreach (TabPage tab in tabSettingGroups.TabPages)
    {
        Panel panel = new Panel()
        {
            Dock = DockStyle.Fill,
            Visible = true
        };

        ListViewItem lvi = new ListViewItem(tab.Text)
        {
            Tag = panel
        };
        lvwOptions.Items.Add(lvi);

        foreach (Control ctrl in tab.Controls)
        {
            panel.Controls.Add(ctrl);
        }
    }

    //Destroy TabControl to free up memory
    tabSettingGroups.Dispose();
}

如果您想重新创建所有内容,则至少需要一个 SplitContainer,ListView 在 SplitContainer.Panel1 中,TabControl 在 SplitContainer.Panel2 中。

如您所见,我已将为每个 TabPage 创建的每个内置 Panel 直接添加到 ListViewItem 的 Tag 属性中。单击 ListViewItem 时,SplitContainer.Panel2 被清空,ListViewItem.Tag 中的 Panel 被添加到 SplitContainer.Panel2

private void lvwOptions_SelectedIndexChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    pnlSettings.Panel1.Controls.Clear();
    Panel pnl = (Panel)e.Item.Tag;
    pnlSettings.Panel1.Controls.Add(pnl);
}

注意:我添加了第二个 SplitContainer 来容纳 TabControl 和 Save/Cancel 按钮,以便这些按钮与 Parent SplitContainer 内联,这样我就不会在按钮左侧创建更多未使用的“空白”。在上面的 _Click 方法中,只需执行 .Panel2(基本上就是您放置 TabControl 的同一个 Panel)。

【问题讨论】:

  • 我的猜测是它们在那里,但不在您当前显示的视图区域中。我不建议使用这种方法来交换用户显示数据。创建包含所有“面板”数据的用户控件,然后将该面板加载到该区域中会更好。
  • 抱歉,我没有百分百关注。你到底是什么意思?
  • 另外,Brian,我检查了 panel.Controls,5 个中只有 3 个在那里。他们肯定没有进入面板的控件列表。
  • 他的意思是,为每组设置控件创建一个自定义的UserControl。 (例如,包含一个面板的用户控件,该面板本身包含所有相关控件。)然后在需要时将该用户控件添加到选项卡面板。动态表单很棒,但有时,您真正需要的只是简单的方法来完成工作。
  • @JamesShaw 所以我的想法是从 TabPage 获取 UserControl 而不是尝试移动控件,我只是移动整个面板,因为它是一个 UserControl,我知道一切都会随之而来它?但是,我无法直接访问 CheckBox Names 以将我的设置分配给它们,这不是问题吗?我可以将面板添加为面板(不使用用户控件),然后移动整个面板(相同的概念),但我仍然可以直接访问代码中的 CheckBox 控件。

标签: c# .net winforms visual-studio-2013


【解决方案1】:

当你迭代它们时,集合正在改变,所以一个简单的技巧就是逆向:

for (int i = tab.Controls.Count - 1; i >= 0; --i) {
  panel.Controls.Add(tab.Controls[i]);
}

或单线:

panel.Controls.AddRange(tab.Controls.Cast<Control>().ToArray());

正如其他用户评论的那样,将每个视图放在单独的 UserControl 中可能更好,而不是尝试移动这些控件 - 这将导致意大利面条式代码尝试管理所有这些更改。

【讨论】:

  • 啊,我明白了。因为我将项目从堆栈中移出,然后新数字引用了其他所有控件,因为所有内容都向上移动了一个。呸。
  • 正是@LarsTech 所说的。随着时间的推移和重复,它将不可避免地导致意大利面条式代码。这很快就会变得难以排除故障。权衡利弊。亲,您将获得一个动态生成的设置列表。缺点可能超过... :)
  • 虽然我将改变处理所有事情的方法(根据上述建议),但从技术上讲,这就是问题的答案。
猜你喜欢
  • 2012-08-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2017-11-04
  • 2018-12-17
相关资源
最近更新 更多