Даже обработчик для ввода текста для предварительного просмотра


В WPF-приложения у меня есть следующий обработчик событий для previewtextinput встречает событие в комбобокс управления. Основной целью этого Кодекса является для выбора элемента в выпадающем списке при нажатии на клавишу буквы. Там дублируется логика в этом коде, и я хочу его удалить.

private void OnTextComboBoxPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var comboBox = sender as ComboBox;
    if (!comboBox.IsDropDownOpen)
    {
        return;
    }

    if (!comboBox.IsEditable || !comboBox.IsReadOnly)
    {
        return;
    }

    foreach (var item in comboBox.Items)
    {
        if (item == null)
        {
            continue;
        }

        var textSearch = TextSearch.GetTextPath(comboBox);

        var stringItem = item as string;
        if (stringItem != null)
        {
            if (stringItem.StartsWith(e.Text, StringComparison.InvariantCultureIgnoreCase))
            {
                SelectItemInComboBox(comboBox, item);
                break;
            }

            continue;
        }

        var dependencyObjItem = item as DependencyObject;
        if (dependencyObjItem != null)
        {
            var textMember = TextSearch.GetText(dependencyObjItem);
            if (!string.IsNullOrEmpty(textMember))
            {
                var selectorFunc = ExpressionHelper.GetMemberFunction(dependencyObjItem, textMember);
                var textValue = selectorFunc(dependencyObjItem);

                if (textValue.ToString().StartsWith(e.Text, StringComparison.InvariantCultureIgnoreCase))
                {
                    SelectItemInComboBox(comboBox, item);
                    break;
                }

                continue;
            }
        }

        if (!string.IsNullOrEmpty(textSearch))
        {
            var selectorFunc = ExpressionHelper.GetMemberFunction(item, textSearch);
            var textValue = selectorFunc(item);

            if (textValue.ToString().StartsWith(e.Text, StringComparison.InvariantCultureIgnoreCase))
            {
                SelectItemInComboBox(comboBox, item);
                break;
            }
        }
    }

    e.Handled = true;
}

private void SelectItemInComboBox(ComboBox comboBox, object item)
{
    var comboBoxItem = comboBox.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
    comboBoxItem.IsSelected = true;
}


1519
7
задан 2 ноября 2011 в 10:11 Источник Поделиться
Комментарии
1 ответ


  1. Я предпочитаю просто колдовать над как , когда я не ожидаю, что объект любого другого типа. Если вы ожидаете этого, использовать как , и будьте уверены, чтобы проверить значение null.

    ВАР комбобокс = (комбобокс)отправителя;


  2. Когда имеет смысл сгруппировать код вместе это делать.

    если (!комбобокс.IsDropDownOpen || !комбобокс.IsEditable || !комбобокс.IsReadOnly)


  3. Пытаюсь использовать LINQ, если это возможно.

  4. Переменные места рядом, где они используются. (текстовый поиск по умолчанию)

  5. Не злоупотребляйте ВАР. Это субъективно, и есть несколько дискуссий об этом. (Также см. комментарии внизу код)

  6. Используя продолжения может сделать его более трудным, чтобы получить представление о коде. В некоторых случаях это полезно, но посмотрите на код ниже, чтобы увидеть, как вы могли заменить его на нормальный , если остальные условия вместо.

  7. Определить избыточный код, посмотрим, что можно исключить и что нельзя. Возможно, придется вводить новые промежуточные переменные. (например, textToCompare)

Вот полный переделанная пример:

private void OnTextComboBoxPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var comboBox = (ComboBox)sender;
if (!comboBox.IsDropDownOpen || !combobox.IsEditable || !combobox.IsReadOnly)
{
return;
}

foreach (var item in comboBox.Items.Where( i => i != null ))
{
string textToCompare = null;

if (item is string)
{
textToCompare = (string)item;
}
else if (item is DependencyObject)
{
DependencyObject dependencyObjItem = (DependencyObject)item;

string textMember = TextSearch.GetText(dependencyObjItem);
if (!string.IsNullOrEmpty(textMember))
{
// From this sample, I don't know what the following type is!
// I wouldn't use var here.
var selectorFunc = ExpressionHelper.GetMemberFunction(dependencyObjItem, textMember);
textToCompare = selectorFunc(dependencyObjItem);
}
}
else
{
string textSearch = TextSearch.GetTextPath(comboBox);
if (!string.IsNullOrEmpty(textSearch))
{
var selectorFunc = ExpressionHelper.GetMemberFunction(item, textSearch);
textToCompare = selectorFunc(item);
}
}

if (textToCompare != null && textToCompare.StartsWith(e.Text, StringComparison.InvariantCultureIgnoreCase))
{
SelectItemInComboBox(comboBox, item);
break;
}
}

e.Handled = true;
}

private void SelectItemInComboBox(ComboBox comboBox, object item)
{
var comboBoxItem = comboBox.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
comboBoxItem.IsSelected = true;
}

Я оставлю это вам в качестве упражнения, можно ли еще устранить дублирование кода из selectorFunc, и будь, что будет полезно.

7
ответ дан 2 ноября 2011 в 04:11 Источник Поделиться