Wpf Comboxbox выбираемый элемент по умолчанию

#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.