views:

211

answers:

3

Hello Good People!!
I bound a datatable to a combobox and defined a dataTemplate in the itemTemplate.i can see desired values in the combobox dropdown list,what i see in the selectedItem is System.Data.DataRowView here are my codes:

 <ComboBox Margin="128,139,123,0" Name="cmbEmail" Height="23" VerticalAlignment="Top" TabIndex="1" ToolTip="enter the email you signed up with here" IsEditable="True" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}">

            <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                      <TextBlock Text="{Binding Path=username}"/>
                </StackPanel>

            </DataTemplate>
        </ComboBox.ItemTemplate>

The code behind is so :

 if (con != null)
 {
    con.Open();
    //users table has columns id | username | pass
    SQLiteCommand cmd = new SQLiteCommand("select * from users", con);
    SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
    userdt = new DataTable("users");
    da.Fill(userdt);
    cmbEmail.DataContext = userdt;

 }

I've been looking for something like SelectedValueTemplate or SelectedItemTemplate to do the same kind of data templating but i found none.

I'll like to ask if i'm doing something wrong or it's a known issue for combobox binding?
if something is wrong in my code please point me to the right direction.
thanks for reading this

+2  A: 

By default the combo box will call ToString() on the selected item to get a value to show - since you are binding to a DataRowView the result is the type (the default behaviour of ToString())

What you actually want to show it the username property of the selected item and to do this you can set the DisplayMemberPath of the combobox to "username"

(Also, if you do this, you'll probably find that you can get rid of the custom datatemplate too, since the username will also be used to populate each item.)


In response to your comment:

I don't want to be one of those programmers, but "it works on my machine".

My XMAL is:

 <ComboBox Name="cmbEmail" 
            Height="23" 
            VerticalAlignment="Top" 
            TabIndex="1" 
            ToolTip="enter the email you signed up with here"
            IsEditable="True"
            IsSynchronizedWithCurrentItem="True" 
            ItemsSource="{Binding}"
            DisplayMemberPath="username">
  </ComboBox> 

and my code behind is:

public partial class Window1 : Window
{
    public Window1()
    {
        Users = new DataTable("users");
        Users.Columns.Add("username");

        Users.Rows.Add(CreateDataRow("Fred"));
        Users.Rows.Add(CreateDataRow("Bob"));
        Users.Rows.Add(CreateDataRow("Jim"));

        InitializeComponent();

        cmbEmail.DataContext = Users;
    }

    public DataTable Users { get; private set; }

    private DataRow CreateDataRow(string userName)
    {
        DataRow dr = Users.NewRow();
        dr["username"] = userName;

        return dr;
    }
}
Martin Harris
thanks for the tip.but there is a problem.I did the displaymemberPath bit and commented the datatemplate part too. what i have as result is the opposite situation where selectedItem is showing properly and the dropdownlist showing the System.Data.DataRowView . I tried to keep them both as in using DisplayMemberPath and ItemTemplate but i catch and exception saying i can't use them both. thanks again for helping out
black sensei
There must be something wrong with my environment then because copy-paste of your code give the same thing as in selectedItem is showing properly and the dropdownlist showing System.Data.DataRowView.Can anyone else try that? thanks
black sensei
A: 

Hello!

I've found out why it wasn't working.Using DisplayMemberPath wasn't working but rather ItemTemplate. Here is an example.

<Window.Resources>
  <DataTemplate x:Key="comboTemplate">
        <TextBlock Text="{Binding Path=username}" />
  </DataTemplate>
</Window.Resources>
<ComboBox Margin="18,121,24,0" Name="cmbEmail" Tag="email" TabIndex="1" ToolTip="enter the email you signed up with here" IsEditable="True" IsSynchronizedWithCurrentItem="True" ItemTemplate="{StaticResource comboTemplate}"  ItemsSource="{Binding}" Height="23" VerticalAlignment="Top" Style="{DynamicResource cmbBoxerrors}">
            <ComboBox.Text>
                <Binding Path="username"/>
            </ComboBox.Text>       
 </ComboBox>

Notice the ItemTemplate

the xaml.cs code hasn't change. thanks for those who read and suggested solutions to me.

black sensei
A: 

i got an answer form msdn and it did it for me

<ComboBox IsEditable="True" ItemTemplate="{StaticResource comboTemplate}" ItemsSource="{Binding}" TextSearch.TextPath="username">

the reason was

Since the ComboBox is set to IsEditable="True", and the ComboBox contains a TextBox element to show the selected value. But the item in the ComboBox is RowView type; it shows the type information not the value in the TextBox.

notice the

TestSearch.TextPath="username"
black sensei