Создать коллекцию с разными типами данных и привязать к списку - PullRequest
3 голосов
/ 21 января 2011

Я пытаюсь создать коллекцию с различными типами данных для привязки к элементу управления списком в Silverlight и C #.

Возможно ли это, если каждый из типов данных реализует интерфейс?

Например, у меня есть отдельные объекты "Скрипка", "Гитара" и "Барабаны", каждый из которых реализует интерфейс "IMusicalInstrument". Могу ли я затем создать список, связать его со списком и, альтернативно, добавить объекты «Скрипка», «Гитара» и «Барабаны» в этот список?

Ответы [ 2 ]

5 голосов
/ 21 января 2011

Да, вы можете, используя список Generic , взглянуть на List<T>.Вы можете создать список с такими инструментами, как этот:

var instruments = new List<IMusicalInstrument> { 
    new Drum(),
    new Guitar(),
    new Violin()
}

, а затем использовать instrumentsListBox.DataSource = instruments;

Однако , если вы хотите упростить для себя, скажитеих для реализации свойств DisplayMember и ValueMember, это то, что ListBox использует для определения того, что отображать и использовать в качестве значения при выборе чего-либо.

0 голосов
/ 21 января 2011

Чтобы прояснить одну вещь, поскольку привязка данных Silverlight не является строго типизированной, различные элементы в списке не обязательно должны поддерживать общий интерфейс.Вероятно, будет лучше, если они это сделают, но все, что им на самом деле нужно - это поддерживать свойства, к которым вы будете привязываться.И если вы хотите получить фантазию, вы можете разделить вашу таблицу данных на разные части, каждая из которых предназначена для отдельного класса, а затем скрыть части, которые не применимы к конкретному отображаемому элементу.Таким образом, у вас может быть совершенно другой интерфейс для барабана, гитары, скрипки и т. Д. Например, допустим, ваши инструменты были определены следующим образом:

public class Drum
{
    public int DrummerCount { get; set; }
}

public class Violin
{
    public int ViolinistCount { get; set; }
}

public class Guitar
{
    public int GuitaristCount { get; set; }
}

Затем вы можете создать ListBox, который будет выглядеть следующим образом:

    <ListBox x:Name="instrumentsListBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock 
                        Visibility="{Binding Converter={StaticResource instrumentVisibilityConverter}, ConverterParameter=Drum}" 
                        Text="{Binding DrummerCount, StringFormat=Drummers:\{0\}, Converter={StaticResource debugConverter}}"/>
                    <TextBlock 
                        Visibility="{Binding Converter={StaticResource instrumentVisibilityConverter}, ConverterParameter=Violin}" 
                        Text="{Binding ViolinistCount, StringFormat=Violinists:\{0\}, Converter={StaticResource debugConverter}}"/>
                    <TextBlock 
                        Visibility="{Binding Converter={StaticResource instrumentVisibilityConverter}, ConverterParameter=Guitar}" 
                        Text="{Binding GuitaristCount, StringFormat=Guitarists:\{0\}, Converter={StaticResource debugConverter}}"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

Обратите внимание, что у каждого класса есть отдельный TextBlock, который используется для его отображения.Видимость каждого TextBlock контролируется с помощью InstrumentVisibilityConverter, который выглядит следующим образом:

public class InstrumentVisibilityConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string expectedType = parameter as string;
        if (value.GetType().Name == expectedType)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

И затем создайте его экземпляр в таком коде (или как вы хотите):

List<object> instruments = new List<object> 
    { 
        new Guitar(), 
        new Guitar(), 
        new Violin(), 
        new Violin(), 
        new Drum() 
    };
instrumentsListBox.ItemsSource = instruments;

Теперь,Я лично думаю (см. здесь ), что привязка данных Silverlight должна быть строго типизированной.Но я, кажется, в меньшинстве там.И до тех пор, пока это не так, нет никаких проблем с тем, чтобы воспользоваться этим.

...