2010-03-11 2 views
3

Я довольно новичок в WPF. У меня есть страница, которая отображает данные из базы данных SQL, используя L2S. L2S возвращает DataTable, который содержит все доступные варианты на выбор для определенной области. Каждая строка, возвращаемая из базы данных, должна быть checkbox, и я хочу поместить эти флажки в stackpanel.Заполнение StackPanel с флажком из базы данных

Я рассматриваю привязку данных к StackPanel? Это неправильно ... Я предполагал, что мне нужно пройти через DataTable и создать элементы флажка для каждой строки, а затем добавить их во время выполнения к StackPanel. Это верно? Возвращает DataTable часть моей проблемы?

Я вижу, что StackPanel имеет свойство DataContext, но я не могу просто установить причину, чтобы он не знал, чтобы каждый элемент был checkbox, правильно?

ответ

8

Возможно, вам нужен элемент ItemsControl. Это позволяет представить ряд элементов, используя указанный DataTemplate. Вы можете сделать это встроенный в ItemsControl:

<ItemsControl ItemsSource="{Binding MyCollectionOfItems}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <CheckBox IsChecked="{Binding NameOfTheCheckedPropertyOnEachItem}"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

или ссылаться на данные шаблона явно из ресурса ... что-то подобное:

<!-- In some parent resource section --> 
    <DataTemplate x:Key="MyDataTemplateName"> 
     <CheckBox IsChecked="{Binding NameOfTheCheckedPropertyOnEachItem}"/> 
    </DataTemplate> 

    <!-- ... --> 

    <ItemsControl ItemsSource="{Binding MyCollectionOfItems}" ItemTemplate="{StaticResource MyDataTemplateName}"> 
    </ItemsControl> 

Или вы можете определить DataTemplate, определяющий внешний вид и почувствуйте себя связанным классом. (Обратите внимание, что если ваш Linq к SQL проецирует в анонимный тип, это не вариант) Что-то вроде:

 <!-- In some parent resource section --> 
     <DataTemplate DataType="{x:Type MyBoundClass}"> 
      <CheckBox IsChecked="{Binding NameOfTheCheckedPropertyOnEachItem}"/> 
     </DataTemplate> 

    <!-- ... --> 

    <ItemsControl ItemsSource="{Binding MyCollectionOfItems}"> 
    </ItemsControl> 

WPF будет искать DataTemplate, который соответствует типу данных каждого из элементов в вашей коллекции. Обратите внимание, что это может быть ОЧЕНЬ полезно для привязки разнородных коллекций, которым нужны разные презентации.

Вы можете привязать DataContext к Stackpanel, но нет встроенной логики повторения шаблона для каждого элемента данных. Он просто предоставляет контекст для дочерних элементов управления и содержит операторы {Binding ...}. Все элементы управления, которые обрабатывают повторяющиеся данные, сходят с ItemsControl и берут свои данные через свойство ItemsSource.

+0

+1 Хороший, тщательный ответ. –

3

В дополнение к ответу Бен Вон Хандорф, я подумал, что было бы полезно упомянуть, что вы также можете изменить способ упорядочения элементов ItemsControl путем изменения ItemsPanel. Например:

<ListBox ItemsSource="{Binding MyCollection}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

Это делает элементы списка ListBox горизонтальными, а не вертикальными. Вы также можете использовать WrapPanel, если хотите, чтобы элементы «текли» как текст (или span, если вы знаете html). WrapPanel также может быть ориентирован горизонтально или вертикально. (Но постарайтесь не использовать WrapPanel для больших коллекций предметов, потому что это не виртуализация, и вызовет некоторое большое отставание.)

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

+1

Отличная точка ... Я должен был это покрыть. Спасибо, что заполнил мою дыру. :) –