djangojazz
djangojazz

Reputation: 13173

Combobox not displaying 'Display Member' properly?

Okay I am not understanding why WPF cannot display the 'Display Member' of a combobox item yet can do the 'selected value'. What is weird is I can explicitly create the display member but not get it back. In my example below I simplified the real world example that would be using ADO.NET to populate the itemsource but the concept is the same. I am generating a combobox that generates at runtime from a sql statement. I want to get the value for one thing but the display for something else. Is there some extra binding or customization I am missing or just the wrong member of .NET? I merely want to get 'Display of ...' to get selected back. If it is not possible that seems kind of weird. All I get back when I select is 'Value' so I know something is being lost in the transfer.

Any ideas?

XAML:

<Window x:Class="WPFComboBoxTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
    <ComboBox x:Name="cmb" Width="100" Height="50"/>
    <TextBlock Height="100"/>
    <Button x:Name="btn" Content="Click" Click="btn_Click" Width="50"/>
    </StackPanel>

C# Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Data;

namespace WPFComboBoxTest
{

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        BindComboBox(cmb);
    }

    public void BindComboBox(ComboBox cbx)
    {
        DataTable dt = new DataTable();

        dt.Columns.Add("Value", typeof(string));
        dt.Columns.Add("Id", typeof(int));

        dt.Rows.Add("Display of One", 1);
        dt.Rows.Add("Display of Two", 2);
        dt.Rows.Add("Display of Three", 3);
        dt.Rows.Add("Display of Four", 4);

        cbx.ItemsSource = dt.DefaultView;
        cbx.DisplayMemberPath = dt.Columns["Value"].ToString();
        cbx.SelectedValuePath = dt.Columns["Id"].ToString();
    }

    private void btn_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Selected Value works: " + cmb.SelectedValue
            + "\n\nSelect Display does not though?: " + cmb.DisplayMemberPath
            );
    }
}
}

Upvotes: 1

Views: 5914

Answers (4)

Try using:

cbx.DisplayMemberPath = "[Value]";
cbx.SelectedValuePath = "[Id]";

It works for me!

Upvotes: 0

Mubarak Shaikh
Mubarak Shaikh

Reputation: 1

Change Your btn_Click event Data as Following:

private void btn_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Selected Value works: " + cmb.SelectedValue
            + "\n\nSelect Display does not though?: " + cmb.Text
    );
}

I think working fine

Upvotes: 0

djangojazz
djangojazz

Reputation: 13173

(facepalm) it was pretty simple. cmb.DisplayMemberPath needs to be cmb.Text. The 'Text' was the property I needed to display the display member shown to the user.

Upvotes: 1

brunnerh
brunnerh

Reputation: 185589

Calling ToString on a column does not sound like a good idea to begin with, not sure how DataTables are mapped but i would try

cbx.DisplayMemberPath = "Value";
cbx.SelectedValuePath = "Id";

Upvotes: 2

Related Questions