#wpf #xaml #combobox
#wpf #xaml #combobox
Вопрос:
У меня есть comboxbox, который привязан к данным observablecollection из моей viewmodel. Я могу заставить свой список заполняться данными, но я также хотел бы добавить элемент по умолчанию, например «— Все модели —«. Приведенный ниже код отображает «—Все модели —» в качестве элемента по умолчанию, но его нельзя выбрать, если вы выберете другой элемент.
<ContentControl Content="{Binding Items}">
<ContentControl.ContentTemplate>
<DataTemplate>
<Grid>
<ComboBox x:Name="cb" ItemsSource="{Binding}"/>
<TextBlock x:Name="tb" Text="--Choose One--" IsHitTestVisible="False" Visibility="Hidden"/>
</Grid>
<DataTemplate.Triggers>
<Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
<Setter TargetName="tb" Property="Visibility" Value="Visible"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
Я пробовал использовать compositecollection, но, похоже, это не сработало. Есть ли способ добиться этого?
Заранее спасибо!
Ответ №1:
CompositeCollection
должно сработать, если вы знаете, как его использовать, то есть; одна важная вещь в этом заключается в том, что он не наследует DataContext
, это означает, что вам нужно ссылаться на свой источник каким-либо другим способом, кроме того, если этот метод является x:Reference
, вы можете не создавать циклическую ссылку, этого можно избежать, поместив коллекцию в ресурсы элемента, на который ссылается. например
<Window.Resources>
<CompositeCollection x:Key="compCollection">
<ComboBoxItem Content="-- All Models --"/>
<CollectionContainer Collection="{Binding MyCollection, Source={x:Reference Window}}"/>
</CompositeCollection>
...
</Window.Resources>
Затем вы можете просто использовать это через ItemsSource="{StaticResource compCollection}"
.
Комментарии:
1. Это гораздо более точный ответ. Намного чище с точки зрения MVVM.
Ответ №2:
Встроите логику взаимодействия с view в viewmodel. мое предложение сделать тип наблюдаемой коллекции viewmodel, который заполняется списком источников, плюс еще одну viewmodel для элемента «не выбран».
что-то вроде
public class ItemViewModel
{
public string Description { get; set; }
public int Id { get; set; }
}
public class ViewModel : ViewModelBase
{
public ObservableCollection<ItemViewModel> Items { get; set; } // Bound to ContentControl
private void Init()
{
Items = new ObservableCollection<ItemViewModel>();
Items.Add(new ItemViewModel() { Description = "--choice one--" , Id = null });
Items.AddRange(Model.Items.Select(i=> new ItemViewModel() { Description = i.Description , Id = i.Id }));
}
}
Затем вы можете обработать идентификатор SelectedItem с семантическим значением null.
Ответ №3:
Вы можете изменить общий тип вашей коллекции на object
и добавить туда -Все модели- thing.