Итерация по TabItems в TabControl - PullRequest
       2

Итерация по TabItems в TabControl

3 голосов
/ 14 декабря 2011

У меня есть tabcontrol с 9 tabitems. Каждая вкладка имеет ряд текстовых полей для ввода данных пользователем. Внизу есть кнопка очистки, подключенная к этому методу:

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, который позволяет пользователю открывать вкладки ClearAll. Прямо сейчас кнопка очистки очищает только то, что находится на текущей выбранной вкладке, и оставляет все остальное в покое. Моя мысль о том, как это сделать, заключалась в том, чтобы перебирать табитемы с помощью этого цикла:

        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);
        }
    }
}

}

Ответы [ 2 ]

4 голосов
/ 14 декабря 2011

WPF отбрасывает все VisualTree из TabItem, которое не выбрано, поэтому на вкладках, которые не видны, фактически не существует элементов управления.

Чтобы сохранить контрольные значения (такие как «Выбор», «Текст» и т. Д.), Их необходимо привязать к чему-либо.Если они связаны с чем-то, тогда ваш метод Clear() должен на самом деле очистить значения Bound, а не значения пользовательского интерфейса.Если они ни к чему не привязаны, то TabControl вернется в исходное состояние при выборе.

2 голосов
/ 14 декабря 2011

Чтобы ваш код работал, вам нужно добавить следующую строку в ваш метод очистки:

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

Метод UpdateLayout заботится о том, чтобы TabItem отображался, а потом VisualTree было доступно.

Как правило, этот подход не очень хорош, и если у вас есть настоящее приложение с бизнес-данными, я бы порекомендовал вам взглянуть на привязку данных / MVVM. Подход должен состоять не в сбросе элементов управления в представлении, а в сбросе связанных бизнес-данных в фоновом режиме.

...