【问题标题】:WPF combobox databinding both to custom objects and to datatable.showing System.Data.DataRowView in dropdown list itemsWPF 组合框数据绑定到自定义对象和数据表。在下拉列表项中显示 System.Data.DataRowView
【发布时间】:2010-06-29 17:01:12
【问题描述】:

我已经发布了一个类似的问题 here 并且无法成功实施向我建议的解决方案,因为它不起作用。我找到了一种方法并希望通过将组合框绑定到来改进它启用数据验证的自定义对象。这里是这个的 xaml

<Window xmlns:data="clr-namespace:Myproject">

<Window.Resources>
  <data:UserLogin x:Key="user"></data:UserLogin>
  <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="Loginname" Source="{StaticResource user}" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </ComboBox.Text>       
 </ComboBox>
</Window>

xaml.cs 是

           if (con != null)
            {
                if (con.State == ConnectionState.Closed)
                    con.Open();

                SqlCeCommand cmdusers = new SqlCeCommand("select * from users order by id", con);

                SqlCeDataAdapter da = new SqlCeDataAdapter(cmdusers);
                userdt = new DataTable("users");
                da.Fill(userdt);

                cmbEmail.DataContext = userdt;

             }  

UserLogin 类是

 class UserLogin :IDataErrorInfo
{
    private string _loginname = "";
    private string _password;


    public string this[string columnName]
    {
        get 
        {  


            string result = null;
            if(columnName == "Loginname")
            {
                if(string.IsNullOrEmpty(this._loginname))
                {
                    result = "Login Name cannot be Empty";
                }
            }

            if (columnName == "Loginname")
            {
                if(!Util.ValidateRegexPatern(Properties.Resources.emailRegex,this._loginname))
                {
                    result = "MalFormed Email address. Please write a correct email addess";
                }
            }

            return result;
        }
    }

    public string Error
    {
        get { return null; }
    }

    public string Password
    {
        get { return _password; }
        set { _password = value; }
    }

    public string Loginname
    {
        get { return _loginname; }
        set { _loginname = value; }
    }
}

问题是当我使用ItemTemplate 时,所选项目显示System.Data.DataRowView 但下拉列表项目显示正确,当我将ItemTemplateDisplayMemberPath 交换时,这是相反的行为,因为所选项目是正确的并且下拉列表项目显示System.Data.DataRowView. 使用它们都会引发异常,因为我不能同时使用它们选择和下拉列表项目都正确显示。

我真的不知道我做错了什么。任何人都可以对此有所了解,我将非常感谢。感谢您阅读本文

【问题讨论】:

    标签: c# wpf xaml combobox binding


    【解决方案1】:

    它是这样的:您将 ComboBox 的数据上下文设置为 DataTable 类型的实例。然后将 ItemsSource 设置为 {Binding},这意味着 ComboBox 中的每个项目都将绑定到 DataRow(既没有登录名,也没有用户名作为属性)。在这里绑定停止工作。没有隐式方法可以将 DataRow 转换为 UserLogin。

    您可以实现一个转换器来进行转换,或者将行一一转换为 UserLogin,并将 ComboBox 的 DataContext 设置为 UserLogin 列表(如果您需要更高级的功能,则设置为 ObservableCollection)。

    在任何一种情况下,删除 &lt;ComboBox.Text&gt; ... &lt;/ComboBox.Text&gt; 部分。

    希望对你有帮助...

    【讨论】:

    • 感谢您的快速回复。我将不得不阅读有关转换器和 observablecollection 的内容,因为我以前没有做过。如果您有一些资源或好的教程,请发布其链接。再次感谢
    • 我现在没有任何例子,但你可以在谷歌上搜索“wpf binding”和“IValueConverter”。基本上,转换器使 UI 能够处理一种类型的数据,而您的视图模型可以处理另一种类型。问候...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    相关资源
    最近更新 更多