ktos1234
ktos1234

Reputation: 207

How to get ComboBox content value?

I would like to get content from my combobox. I already tried some ways to do that, but It doesn't work correctly.

This is example of my combobox:

<ComboBox x:Name="cmbSomething" Grid.Column="1" Grid.Row="5" HorizontalAlignment="Center" Margin="0 100 0 0" PlaceholderText="NothingToShow">
    <ComboBoxItem>First item</ComboBoxItem>
    <ComboBoxItem>Second item</ComboBoxItem>
</ComboBox>

After I click the button, I want to display combobox selected item value.

string selectedcmb= cmbSomething.Items[cmbSomething.SelectedIndex].ToString();
await new Windows.UI.Popups.MessageDialog(selectedcmb, "Result").ShowAsync();

Why this code does not work? My result instead of showing combobox content, it shows this text:

Windows.UI.Xaml.Controls.ComboBoxItem

Upvotes: 0

Views: 4355

Answers (2)

Salah Akbari
Salah Akbari

Reputation: 39966

You need the Content property of ComboBoxItem. So this should be what you want:

var comboBoxItem = cmbSomething.Items[cmbSomething.SelectedIndex] as ComboBoxItem;
if (comboBoxItem != null)
{
    string selectedcmb = comboBoxItem.Content.ToString();
}

Upvotes: 2

Chris Fannin
Chris Fannin

Reputation: 1294

I have expanded on my suggestion regarding using models instead of direct UI code-behind access. These are the required parts:

BaseViewModel.cs

I use this in a lot of the view models in my work project. You could technically implement it directly in a view model, but I like it being centralized for re-use.

public abstract class BaseViewModel : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private Hashtable values = new Hashtable();

  protected void SetValue(string name, object value)
  {
     this.values[name] = value;
     OnPropertyChanged(name);
  }

  protected object GetValue(string name)
  {
     return this.values[name];
  }

  protected void OnPropertyChanged(string name)
  {
     PropertyChangedEventHandler handler = PropertyChanged;
     if (handler != null)
     {
        handler(this, new PropertyChangedEventArgs(name));
     }
  }
}

ComboViewModel.cs

This what you'll bind to make it easy to get values. I called it ComboViewModel because I'm only dealing with your ComboBox. You'll want a much bigger view model with a better name to handle all of your data binding.

public class ComboViewModel : BaseViewModel
{

  public ComboViewModel()
  {
     Index = -1;
     Value = string.Empty;
     Items = null;
  }

  public int Index
  {
     get { return (int)GetValue("Index"); }
     set { SetValue("Index", value); }
  }
  public string Value
  {
     get { return (string)GetValue("Value"); }
     set { SetValue("Value", value); }
  }
  public List<string> Items
  {
     get { return (List<string>)GetValue("Items"); }
     set { SetValue("Items",value); }
  }
}

Window1.xaml

This is just something I made up to demonstrate/test it. Notice the various bindings.

<Window x:Class="SO37147147.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
      <Grid.RowDefinitions>
         <RowDefinition Height="Auto" />
         <RowDefinition Height="*" />
         <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <ComboBox x:Name="cmbSomething" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" HorizontalAlignment="Center" MinWidth="80"
                ItemsSource="{Binding Path=Items}" SelectedIndex="{Binding Path=Index}" SelectedValue="{Binding Path=Value}"></ComboBox>
      <TextBox x:Name="selectedItem" MinWidth="80" Grid.Row="2" Grid.Column="0" Text="{Binding Path=Value}" />
      <Button x:Name="displaySelected" MinWidth="40" Grid.Row="2" Grid.Column="1" Content="Display" Click="displaySelected_Click" />
   </Grid>
</Window>

Window1.xaml.cs

Here's the code-behind. Not much to it! Everything is accessed through the dataContext instance. There's no need to know control names, etc.

public partial class Window1 : Window
{
  ComboViewModel dataContext = new ComboViewModel();

  public Window1()
  {
     InitializeComponent();
     dataContext.Items=new List<string>(new string[]{"First Item","Second Item"});
     this.DataContext = dataContext;
  }

  private void displaySelected_Click(object sender, RoutedEventArgs e)
  {
     MessageBox.Show(String.Format("Selected item:\n\nIndex: {0}\nValue: {1}", dataContext.Index, dataContext.Value));
  }
}

You can add business logic for populating models from a database, saving changes to a database, etc. When you alter the properties of the view model, the UI will automatically be updated.

Upvotes: 0

Related Questions