Есть ли способ заполнить список как статическими, так и динамическими элементами?
Я пишу приложение для Windows Phone 7 и хотел бы иметь один статический listboxItem вверху или внизу, а затем связывать другие элементы из viewModel. Я попытался установить как статический listboxItem, так и dataTemplate, но статический элемент заменен динамическими элементами.
Редактировать:
Я нашел несколько сообщений, в которых показано, как создать настраиваемый элемент управления, унаследованный от списка, который позволяет использовать несколько шаблонов. Как я могу создать настраиваемый элемент управления, который добавляет раздел для статических элементов, которые всегда присутствуют независимо от привязки.
Ответ 1 · рейтинг 1 · Dan Auclair
Если вы пытаетесь выполнить MVVM и также выполняете двустороннюю привязку SelectedItem ListBox, будет намного проще / чище просто привязать одну коллекцию к свойству ItemsSource.
Можете ли вы просто предварительно заполнить коллекцию в вашей ViewModel статическим элементом? Затем вы можете объединить свои динамические элементы в уже существующую коллекцию, когда они будут доступны (возвращение из веб-службы или что-то еще). Похоже, вам все равно нужна такая логика в вашей ViewModel, и вы просто выставите один список в View для использования с ListBox.
Ответ 2 · Dan Auclair
Поскольку существует два разных типа элементов, я думаю, что лучше всего было бы создать собственный подкласс ListBox, который добавляет новое свойство DependencyProperty, позволяющее связывать и отображать второй список. Это также потребует нового стиля по умолчанию для правильного отображения второго списка в том же ScrollViewer, что и обычный <ItemsPresenter/>.
Вот пример моего настраиваемого ListBox, позволяющего это:
public class MyListBox : ListBox
{
public MyListBox()
: base()
{
this.DefaultStyleKey = typeof(MyListBox);
}
public static readonly DependencyProperty StaticItemsProperty = DependencyProperty.Register(
"StaticItems",
typeof(IList),
typeof(MyListBox),
null);
public IList StaticItems
{
get { return (IList)GetValue(StaticItemsProperty); }
set { SetValue(StaticItemsProperty, value); }
}
}
Затем вам нужно будет скопировать весь стиль ListBox по умолчанию в словарь ресурсов themes / generic.xaml и изменить его, чтобы он стал стилем по умолчанию для элемента управления MyListBox. Единственное, что я изменил из стиля по умолчанию (помимо атрибута TargetType), - это содержимое ScrollViewer, у которого был исходный список:
<Style TargetType="custom:MyListBox">
<!-- all the same old XAML for the normal ListBox -->
<ScrollViewer x:Name="ScrollViewer" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}">
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{TemplateBinding StaticItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsPresenter/>
</StackPanel>
</ScrollViewer>
<!-- rest of the same old ListBox XAML -->
</Style>
Как вы можете видеть, я изменил ScrollViewer, который обычно просто содержал ItemsPresenter для ListBox, и заменил его StackPanel, содержащим новый ItemsControl, связанный с новым StaticItems DependencyProperty, который я добавил в MyListBox. Я изменил DataTemplate для этого ItemsControl, чтобы отобразить TextBox. Обычный ItemsPresenter с обычным ItemsTemplate затем отобразится под статическим списком в ScrollViewer.
Затем этот настраиваемый ListBox можно использовать вместо обычного ListBox для привязки к двум разным спискам в вашей ViewModel, как к вашим статическим элементам, так и к вашим динамическим элементам.
<custom:MyListBox x:Name="ListBox" ItemsSource="{Binding DynamicItems}" StaticItems="{Binding StaticItems}"/>