2015-01-10 3 views
1

У меня есть серия списков и comboboxes, которые я хочу обновить, так что перечисленные элементы те же, что и перечисленные в IEnumerable<string>. Я понимаю, что привязка данных может помочь, но я думаю, что теперь это может быть битва, и я бы предпочел избежать этого. я написал что-то вроде этого:Вызов той же функции с ListBox или ComboBox

public static void UpdateListboxWithStrings(
     ListControl listcontrol, 
     IEnumerable<string> stringlist) 
    { 
     Object listcontrolitems; 
     if (listcontrol is ListBox) 
     { 
      listcontrolitems = 
       ((ListBox)listcontrol).Items; 
     } 
     else if (listcontrol is ComboBox) 
     { 
      listcontrolitems = 
       ((ComboBox)listcontrol).Items; 
     } 
     else 
     { 
      //// Wrong control type. 
      //// EARLY EXIT 
      return; 
     } 
     int itemscount = listcontrolitems.Count; 
     /// More code here... 
    } 

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

Как вы пишете функцию, которая работает с выпадающим списком или в списке без дублирования кода?

LE. Это приложение Windows, NET Framework 4.5 с использованием System.Windows.Forms. Я хочу добавить/удалить элементы, подсчитать, получить и установить выделение. Кроме того, могут быть дубликаты. Поэтому преобразование в элементы в строки не будет работать.

+0

Что вы имеете в виду под «работать с выпадающий список»? Если у вас есть новый метод, который вы хотите реализовать, расширьте исходный элемент управления. В качестве альтернативы вы можете передать элемент управления определенному пользователем методу. – NoChance

+1

Какая структура графического интерфейса вы используете? Это важно. Правильный ответ в значительной степени зависит от контекста. Если вы используете Winforms, вы не можете назначить один и тот же тип коллекции из двух разных подклассов ListControl для одной и той же переменной; они не связаны. Вы можете, однако, разыменовать коллекцию в ветви типа вашего кода, сохранив свойство 'Count' в локальной переменной' int', которая, конечно же, может быть разделена. –

+0

@PeterDuniho Как сказано в отредактированном ответе Windows Application. –

ответ

1

Вы не сможете сделать это удобным способом, если только вам не нужны функции, доступные в IList. В этом случае вы можете пропустить описанную ниже оболочку и просто объявить локальную переменную items как IList, присвоив ее непосредственно свойству Items в каждом ветви if, относящемся к типу управления.

Если все, что вам нужно было значение Count свойства можно назначить локальную int переменного в каждой ветви типоспецифичного (т.е. в блоках if заявления).

Но вы заявляете, что хотите на самом деле манипулировать коллекциями. Коллекции System.Windows.Forms.ComboBox.Items и System.Windows.Forms.ListBox.Items представляют собой два совершенно разных, несвязанных типа. Поэтому, если вы не можете использовать IList, единственным способом, с помощью которого вы могли бы использовать код, который ими управляет, было бы объединение коллекций в новый тип, который понимает оба.

Например:

abstract class ListControlItems 
{ 
    public abstract int Count { get; } 
    public abstract int Add(object item); 
    public abstract void RemoveAt(int index); 
    // etc. 
} 

class ListBoxControlItems : ListControlItems 
{ 
    private ListBox.ObjectCollection _items; 

    public ListBoxControlItems(ListBox.ObjectCollection items) 
    { 
     _items = items; 
    } 

    public override int Count { get { return _items.Count; } } 
    public override int Add(object item) { return _items.Add(item); } 
    public override void RemoveAt(int index) { _items.RemoveAt(index); } 
    // etc. 
} 

Сделайте то же самое для ComboBoxControlItems типа. Тогда в обработчике, вы можете создать соответствующий абстрактный тип, и использовать его для управления коллекциями:

public static void UpdateListboxWithStrings(
    ListControl listcontrol, 
    IEnumerable<string> stringlist) 
{ 
    ListControlItems items; 

    if (listcontrol is ListBox) 
    { 
     items = new ListBoxControlItems(((ListBox)listcontrol).Items); 
    } 
    else if (listcontrol is ComboBox) 
    { 
     items = new ComboBoxControlItems(((ComboBox)listcontrol).Items); 
    } 
    else 
    { 
     //// Wrong control type. 
     //// EARLY EXIT 
     return; 
    } 

    int itemscount = items.Count; 
    /// More code here... 
} 
+0

Выглядит многообещающе в теории, но на самом деле легче дублировать код. –

+0

Да, это не так удобно. Вы пытались использовать 'IList'? Из вашего вопроса было неясно, какие операции вам нужны, но почти все, что может сделать любая из наборов, специфичных для управления, интерфейс 'IList' может также (главное, что мне кажется, отсутствует, это' AddRange() ' метод). Одним из основных аргументов в пользу абстракции является обычный «СУХОЙ»: как только вы копируете/вставляете код, теперь у вас есть два разных места, которые, если они когда-либо меняются, вам также нужно запомнить и другое. –

+0

Нет, есть выбор, с которым нужно иметь дело, и это сильно отличается от одного окна к другому. Часть выбора поддерживает случай хранения кода списка отдельно от поля со списком. –

Смежные вопросы