如何将数据表绑定到wpf可编辑组合框:selectedItem显示System.Data.DataRowView

时间:2010-05-19 12:01:42

标签: c# wpf data-binding wpf-controls binding

我将数据表绑定到组合框并在itemTemplate.i中定义了一个dataTemplate,可以在组合框下拉列表中看到所需的值,我在selectedItem中看到的是System.Data.DataRowView这里是我的代码:

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

背后的代码是这样的:

 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;

 }

我一直在寻找像SelectedValueTemplate或SelectedItemTemplate这样的东西来做同样的数据模板,但我找不到。

我想问一下我做错了什么,或者这是组合框绑定的已知问题?
如果我的代码出了问题,请指出正确的方向  感谢您阅读本文

3 个答案:

答案 0 :(得分:3)

默认情况下,组合框将调用所选项目上的ToString()以获取要显示的值 - 因为您绑定到DataRowView,结果是类型(ToString()的默认行为)

您实际想要显示所选项目的用户名属性,为此您可以将组合框的DisplayMemberPath设置为“用户名”

(另外,如果你这样做,你可能会发现你也可以摆脱自定义数据模板,因为用户名也将用于填充每个项目。)


回应你的评论:

我不想成为那些程序员之一,但“它可以在我的机器上运行”。

我的XMAL是:

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

我背后的代码是:

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

答案 1 :(得分:1)

我得到了一个msdn的答案,它为我做了

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

原因是

  

由于ComboBox设置为IsEditable =“True”,并且ComboBox包含一个TextBox元素以显示所选值。但是ComboBox中的项是RowView类型;它显示的是类型信息,而不是TextBox中的值。

注意

TestSearch.TextPath="username"

答案 2 :(得分:0)

我发现了为什么它不起作用。使用DisplayMemberPath不起作用,而是使用ItemTemplate。 这是一个例子。

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

注意ItemTemplate

xaml.cs代码没有改变。感谢那些阅读并向我提出解决方案的人。