【问题标题】:Iterate through TabItems in a TabControl遍历 TabControl 中的 TabItems
【发布时间】:2012-01-20 09:23:33
【问题描述】:

我有一个 tabcontrol,里面有 9 个 tabitem。每个选项卡都有一系列文本框供用户输入数据。底部是一个清除按钮,与此方法挂钩:

public void ClearTextBoxes()
    {
        ChildControls ccChildren = new ChildControls();

        foreach (object o in ccChildren.GetChildren(rvraDockPanel, 2))
        {
            if (o.GetType() == typeof(WatermarkTextBox) || o.GetType() == typeof(DateBox) ||
                o.GetType() == typeof(DigitBox) || o.GetType() == typeof(PhoneBox))
            {
                WatermarkTextBox water = (WatermarkTextBox)o;
                water.Text = "";
            }
            else if (o.GetType() == typeof(ComboBox))
            {
                ComboBox combo = (ComboBox)o;
                combo.SelectedIndex = -1;
            }
            else if (o.GetType() == typeof(CheckBox))
            {
                CheckBox check = (CheckBox)o;
                check.IsChecked = false;
            }
        }
    }

这工作得很好,但是我也有一个 MenuItem 允许用户清除所有选项卡。现在,清除按钮仅清除当前选定选项卡上的内容,而将其他所有内容单独保留。我对如何做到这一点的想法是用这个循环遍历 tabitems:

        for (int i = 0; i < 10; i++ )
        {
            tabSelection.SelectedIndex = i;
            clearButton_Click(null, null);
        }

它将翻阅所有选项卡,但不会清除任何内容。我尝试使用自动化,但结果相同。它似乎不会清除任何东西。

ChildControls 类:

class ChildControls
{
private List<object> listChildren;

public List<object> GetChildren(Visual p_vParent, int p_nLevel)
{
    if (p_vParent == null)
    {
        throw new ArgumentNullException("Element {0} is null!", p_vParent.ToString());
    }

    this.listChildren = new List<object>();

    this.GetChildControls(p_vParent, p_nLevel);

    return this.listChildren;

}

private void GetChildControls(Visual p_vParent, int p_nLevel)
{
    int nChildCount = VisualTreeHelper.GetChildrenCount(p_vParent);

    for (int i = 0; i <= nChildCount - 1; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(p_vParent, i);

        listChildren.Add((object)v);

        if (VisualTreeHelper.GetChildrenCount(v) > 0)
        {
            GetChildControls(v, p_nLevel + 1);
        }
    }
}

}

【问题讨论】:

  • 我认为这与使用 TabControl 的 WPF 行为有关。我已经读过,当一个选项卡消失时,前一个选项卡的可视化树会被“丢弃”。您可能希望将 Clear() 抽象为一个类。

标签: c# wpf button tabs automation


【解决方案1】:

要使您的代码正常工作,您需要将以下行添加到您的清理方法中:

        tabControl.SelectedIndex = i;
-->        UpdateLayout();
        Button_Click(null, null);

UpdateLayout 方法负责绘制 TabItem 并且之后可以使用 VisualTree。

通常这种方法并不好,如果你有一个真正的应用程序,背后有业务数据,我建议你看看数据绑定/MVVM。该方法不应该是在视图中重置您的控件,而是在后台重置您绑定的业务数据。

【讨论】:

  • 感谢您的帮助。我一直在尝试更多地了解 MVVM,但不知道从哪里开始。您能推荐任何入门指南/书籍吗?
  • 不客气。只需在 SO 上搜索,您就会找到数十条建议 ..stackoverflow.com/search?q=MVVM+tutorial
  • 为此苦苦挣扎了一天,终于找到了解决办法。当你想找到一个控件时,Winforms 与 wpf 相比是如此简单!
【解决方案2】:

WPF 会丢弃未选中的 TabItem 中的整个 VisualTree,因此在不可见的选项卡上实际上不存在任何控件。

要维护控制值(例如选择、文本等),它们需要绑定到某些东西。如果它们绑定到某些东西,那么您的 Clear() 方法实际上应该清除 Bound 值,而不是 UI 值。如果它们没有绑定到任何东西,那么TabControl 将在被选中时恢复到其初始状态。

【讨论】:

  • 我将 SvenG 的评论标记为答案,因为它在这种情况下确实有效。不过,我投了你的票,因为它让我开始真正了解 MVVM 的工作原理,并了解它会变得多么容易。我在想我的下一个主要项目是将我拥有的东西转换为 MVVM。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2010-12-17
  • 2012-01-29
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多