1

I am developing a WPF application using MVVM pattern, I have a combobox with itemssource bounded from viewmodel, I want to have a Default option in the combobox like "--Select user--", what is the best approach to do this. This is my XAML code:

<ComboBox Grid.Column="1" HorizontalAlignment="Left" Margin="5.2,8.2,0,7.8" Grid.Row="5" Width="340" ItemsSource="{Binding Path=Users}" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding SelectedUser}" Grid.ColumnSpan="2">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock.Text>
                            <MultiBinding StringFormat="{}{0} {1}">
                                <Binding Path="FirstName"/>
                                <Binding Path="LastName"/>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
</ComboBox>
Muds
  • 4,006
  • 5
  • 31
  • 53
naufal_chiadmi
  • 301
  • 1
  • 4
  • 14
  • @PaulB's answer on the question "[How to display default text “--Select Team --” in combo box on pageload in WPF?](https://stackoverflow.com/questions/1426050/how-to-display-default-text-select-team-in-combo-box-on-pageload-in-wpf)" worked for me – alvinchesaro Oct 05 '19 at 11:57

4 Answers4

0
<ComboBox>
SelectedIndex="0"
<ComboBox.ItemsSource>
    <CompositeCollection>
        <ListBoxItem>Please Select</ListBoxItem>
        <CollectionContainer Collection="{Binding Source={StaticResource YOURDATASOURCE}}" />
    </CompositeCollection>
</ComboBox.ItemsSource>
Tharif
  • 13,794
  • 9
  • 55
  • 77
0

Easiest approach is to have such item in your bound list/collection. After you have done populating list in your view model simply do

myViewModel.Users.Insert(0, "--Select user--");

Its a pseudo code, so please adjust.

VidasV
  • 4,335
  • 1
  • 28
  • 50
  • assuming Users is a collection of string ? – Muds Apr 30 '15 at 07:21
  • That is why I wrote that it is a pseudo code, because I am not aware of the specification of "User" class – VidasV Apr 30 '15 at 07:25
  • yea, so if user is an object do you recommend to add a new object ? – Muds Apr 30 '15 at 07:32
  • Yes, having it as default/null value object – VidasV Apr 30 '15 at 07:37
  • and when you save the collection then have checks for default or null value to not go in database ? doesn't sound too good to me really rest on OP – Muds Apr 30 '15 at 07:46
  • I agree that this is not the best solution if there is a DB and there is a need of validation, but having an alternative should not hurt anyone. – VidasV Apr 30 '15 at 07:49
0

Well another approach can be to have a trigger and let the comboboxitems as they were

<Grid>
    <ComboBox x:Name="mycombo" ItemsSource="{Binding}"/>
    <TextBlock Text="-- Select User --" IsHitTestVisible="False" Visibility="Hidden">
           <TextBlock.Style>
                <Style TargetType="TextBlock">
                      <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=mycombo,Path=SelectedItem}" Value="{x:Null}">
                                  <Setter Property="Visibility" Value="Visible"/>
                             </DataTrigger>
                      </Style.Triggers>
                </Style>
           </TextBlock.Style>
     </TextBlock>
</Grid>

Or if you can afford to change the appearance of your combobox to look like an editable combobox you can do this --

<ComboBox IsEditable="True" IsReadOnly="True" Text="-- Select User --" />
Muds
  • 4,006
  • 5
  • 31
  • 53
0

If you're using MVVM, then your Select user item should be in a collection in your view model along with all of you other items. There are several ways of achieving this, depending on the type of your data items.

If you're just using plain strings, then it's easy... just add a string into the data bound collection in the first index:

DataBoundCollection.Insert(0, "--Select user--");

If your data type is a custom class, then you could use the string property that is used to display the item's name/identifier to hold that value:

DataBoundCollection.Insert(0, new YourDataType("--Select user--", null, null, 0, 0));

One other option would be to make the DataBoundCollection a collection of a base type. The normal items should derive this base type and so can be added into this collection. The default item could be another derived type (so that it can be displayed differently) that can also be added to the same collection:

// You could even hard code this text into the DefaultType object alternatively
DataBoundCollection.Add(new DefaultType("--Select user--"));
DataBoundCollection.Add(new YourDataType(...));
DataBoundCollection.Add(new YourDataType(...));
...
DataBoundCollection.Add(new YourDataType(...));

You can then display them differently in the ComboBox using DataTemplates that do not have the x:Key directive set on them:

<DataTemplate DataType="{x:Type Local:YourDataType}">
    <!-- Define how your normal items are displayed here -->
</DataTemplate>
<DataTemplate DataType="{x:Type Local:DefaultType}">
    <!-- Define how your default item is displayed here -->
</DataTemplate>
Sheridan
  • 68,826
  • 24
  • 143
  • 183