Аккордеон привязки данных к общему списку в Silverlight - PullRequest
3 голосов
/ 23 февраля 2011

Дан список объектов, содержащих два свойства (IdentityType и Name) в формате:

IdentityType | Name
A | One  
A | Two  
A | Three  
B | Four  
B | Five  
C | Six  

Есть ли способ декларативно связать данные, чтобы аккордеон отображался так?

A
- One
- Two
- Three
B
- Four
- Five
C
- Six

Пока лучшее, что я могу получить, это заголовок панели для каждого элемента, например:

<toolkit:Accordion ItemsSource="{Binding Path=Identities}" Grid.Row="2" SelectionMode="ZeroOrMore">
        <toolkit:Accordion.ItemTemplate>
            <DataTemplate >
                <TextBlock Text="{Binding IdentityType, Converter={StaticResource EnumDescriptionConverter}}"/>
            </DataTemplate>
            </toolkit:Accordion.ItemTemplate>
            <toolkit:Accordion.ContentTemplate>
            <DataTemplate>
                <StackPanel Margin="5" Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}" Foreground="White" />
                </StackPanel>
            </DataTemplate>
        </toolkit:Accordion.ContentTemplate>
    </toolkit:Accordion>

Я новичок в Silverlight, поэтому я мог упустить что-то ослепительно очевидное, но любая помощь будет очень признательна!

Ответы [ 2 ]

5 голосов
/ 08 марта 2011

Вы можете сделать это с моделью представления между вашей моделью (список initail) и вашим представлением (разметка).

  • Создать класс модели представления с Title и NameCollection
  • Используйте LINQ (или простой foreach), чтобы перевести существующий список из 6 сущностей в список из 3 сущностей с 3, 2 и 1 именами в их коллекции имен соответственно.
  • Привязать источник элементов Accordions кколлекция объектов ViewModel.
  • Свяжите текстовый блок в шаблоне заголовка вашего элемента аккордеона с вашим свойством Title
  • Добавьте повторяющийся элемент управления, например ItemsControl, в ваш шаблон содержимого элемента аккордеона
  • Свяжите свой повторяющийся элемент с коллекцией NamesCollection

Предполагается, что ваша модель выглядит следующим образом ...

public class Model
{
    public string Title { get; set; }
    public string Name { get; set; }
}

Структура вашей модели представления должна быть ...

public class ViewModel
{
    public string Title { get; set; }
    public List<string> Names { get; set; }
}

public class DataContextClass
{
    public DataContextClass()
    {
        var modelData = new ModelData();

        var query = from m in modelData.ModelCollection
                    group m by m.Title
                    into vm select new ViewModel { Title = vm.Key, Names = vm.Select(x => x.Name).ToList() };
        ViewModelCollection = query.ToList();
    }

    public List<ViewModel> ViewModelCollection { get; set; }
}

Тогда ваше представление может создать экземпляр вашего DataContextClass, назначить его собственному свойству DataContext и затем использовать эту разметку ...

<layout:Accordion ItemsSource="{Binding Path=ViewModelDataInstance.ViewModelCollection}" >
    <layout:Accordion.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" />
        </DataTemplate>
    </layout:Accordion.ItemTemplate>
    <layout:Accordion.ContentTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding Path=Names}" />
        </DataTemplate>
    </layout:Accordion.ContentTemplate>
</layout:Accordion>
2 голосов
/ 23 апреля 2012

Вы также можете использовать Tuple.Код становится:

public class DataContextClass{
public DataContextClass()
{
    var modelData = new ModelData();

    var query = from m in modelData.ModelCollection
                group m by m.Title
                into vm select Tuple.Create(vm.Key,  vm.Select(x => x.Name).ToList() };
    Collection = query.ToList();
}

public Tuple<string,List<string>> Collection { get; set; }

}

Xaml становится:

<layout:Accordion ItemsSource="{Binding Path=ViewModelDataInstance.ViewModelCollection}" >
<layout:Accordion.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Item1}" />
    </DataTemplate>
</layout:Accordion.ItemTemplate>
<layout:Accordion.ContentTemplate>
    <DataTemplate>
        <ItemsControl ItemsSource="{Binding Path=Item2}" />
    </DataTemplate>
</layout:Accordion.ContentTemplate>

Надеюсь, это поможет

...