1

Following code of my WPF app is showing the default value as blank instead of CA. I've tested in debug mode that the cmbStates.SelectedValue is showing NULL after I move to the next line while using F11 in VS2017. I've tried moving the code to Windows loaded event but still the exact same behavior.

Note:

  1. According to this post it should work, but it's not. Maybe, my case is a bit different
  2. The code successfully displays the comboBox values but the top of the comboBox is blank unless I manually select a particular value for the comboBox.

Question: What I may be missing here and how can we make it work?

XAML:

<Window x:Class="WpfTestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
....
....
>
 <Grid>
....
....
<ComboBox x:Name="cmbStates" IsEditable="True" SelectedValuePath="Content" SelectionChanged="cmbStates_SelectionChanged" />
....
....

  </Grid>
</Window>

Code Behind for MainWindow:

....
public MainWindow()
{
    InitializeComponent();

    cmbStates.ItemsSource = new List<string>() {"OH", "VA", "CA", "TN", "CA", "DE"};
    cmbStates.SelectedValue =  "CA";
}
....

UPDATE:

Please note that the question is more specific to setting the default value in Code Behind and not in XAML because the list is quite longer than shown in this post (for brevity), and that the default value is not always "CA" - it varies based on the business requirements. You can think of "CA" as some string variable value instead, but the idea is the same.

nam
  • 21,967
  • 37
  • 158
  • 332
  • Try `SelectedItem`... `SelectedValue` has another use case. See: https://blogs.msdn.microsoft.com/jaredpar/2006/11/07/combobox-selecteditem-selectedvalue-selectedwhat/ – Glenn Ferrie May 12 '19 at 00:19
  • @GlennFerrie I had already tried `SelectedItem` but that also returns `NULL`. – nam May 12 '19 at 01:06
  • Remove SelectedValuePath="Content" in your combobox.. – AmRo May 12 '19 at 06:40

2 Answers2

1

Since you set the ItemsSource of your ComboBox to a List<string>, you should set the SelectedItem property to a string that is included in this list and remove SelectedValuePath="Content" from your XAML as a string has no Content property:

cmbStates.ItemsSource = new List<string>() {"OH", "VA", "CA", "TN", "CA", "DE"};
cmbStates.SelectedItem =  "CA";

XAML:

<ComboBox x:Name="cmbStates" IsEditable="True" SelectionChanged="cmbStates_SelectionChanged" />
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Sorry for marking it late as an `Answer`. It works for strings (+1 my upvote, as well). It does not however work for a list of `double`. E.g., following code does not set the default value of combobox to 9: `cmbFontSize.ItemsSource = new List() { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 }; cmbFontSize.SelectedItem = 9;` – nam May 09 '21 at 22:01
0

The issue why the selected item is not displayed is this xml attribute:

SelectedValuePath="Content"

While the SelectedValue is set to "CA", it is not displayed, because you advised your view to check for the property Content for the SelectedItem, which of course is not present for the string that you use.

In order to make it work for your above example, you would simply remove that attribute within your combobox.

On the other hand, if your bound items are classes and you would need one field to display and another one as the value / identifier, the SelectedValuePath would make sense, in combination with the DisplayMemberPath attribute.

Let's say your items would look something like this:

public class SomeModel
{
    public string Abbreviation { get; set; }
    public string Content { get; set; }

    public SomeModel(string abbreviation, string content)
    {
        Abbreviation = abbreviation;
        Content = content;
    }
}

In this case the ComboBox would look like this:

<ComboBox x:Name="cmbStates" IsEditable="True" SelectedValuePath="Abbreviation" DisplayMemberPath="Content" SelectionChanged="cmbStates_SelectionChanged" />

This way the Abbreviation property is the actuall value of the ComboBoxItem and the Content is used as the display for the ComboBox. Now your MainWindow constructor would look like this:

public MainWindow()
{
    InitializeComponent();

    cmbStates.ItemsSource = new List<SomeModel>
    {
        new SomeModel("OH","Ohio"), new SomeModel("VA","Virginia"), new SomeModel("CA","California "),
        new SomeModel("TN","Tennessee"), new SomeModel("DE","Delaware")
    };
    cmbStates.SelectedValue = "CA";
}

Besides this case, I would advise yout to look into WPF data binding and WPF MVVM pattern.

Raul
  • 2,745
  • 1
  • 23
  • 39