How to bind a datatable to a wpf editable combobox: selectedItem showing System.Data.DataRowView

六眼飞鱼酱① 提交于 2019-12-24 07:28:46

问题


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


回答1:


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;
    }
}



回答2:


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"



回答3:


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.



来源:https://stackoverflow.com/questions/2865231/how-to-bind-a-datatable-to-a-wpf-editable-combobox-selecteditem-showing-system

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!