【问题标题】:How to bind a datatable to a wpf editable combobox: selectedItem showing System.Data.DataRowView如何将数据表绑定到 wpf 可编辑组合框:selectedItem 显示 System.Data.DataRowView
【发布时间】:2011-02-21 08:31:26
【问题描述】:

我将一个数据表绑定到一个组合框并在 itemTemplate 中定义了一个 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 这样的东西来做同样类型的数据模板,但我没有找到。

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

【问题讨论】:

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


    【解决方案1】:

    默认情况下,组合框将对所选项目调用 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;
        }
    }
    

    【讨论】:

    • 感谢提示。但有一个问题。我做了 displaymemberPath 位并评论了 datatemplate 部分。我得到的结果是 selectedItem 正确显示和下拉列表显示 System.Data.DataRowView 的相反情况。我试图让它们都像使用 DisplayMemberPath 和 ItemTemplate 一样,但我发现异常说我不能同时使用它们。再次感谢您的帮助
    • 我的环境一定有问题,因为您的代码的复制粘贴给出的结果与 selectedItem 中的内容相同,并且下拉列表显示 System.Data.DataRowView。其他人可以尝试吗?谢谢
    【解决方案2】:

    我收到了一份 msdn 的答复,它帮我完成了

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

    原因是

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

    注意

    TestSearch.TextPath="username"
    

    【讨论】:

    • 我知道这是一个老问题,但是当你合并你的答案时会更容易阅读。
    【解决方案3】:

    我发现它为什么不起作用。使用 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 代码没有改变。感谢那些阅读并向我提出解决方案的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多