2010-05-06 13 views
5

我在SQL Server中的表看起来像这样:正确的数据绑定到组合框和处理其事件

ID Code Name  Surname 
1 MS Mike  Smith 
2 JD John  Doe 
3 UP Unknown Person 

等等...

现在我要绑定从这个数据表以ComboBox的方式显示在ComboBox中,我已经从Code列显示值。

我做这样的绑定:

SqlDataAdapter sqlAdapter = new SqlDataAdapter("SELECT * FROM dbo.Users ORDER BY Code", MainConnection); 
sqlAdapter.Fill(dsUsers, "Users"); 
cbxUsers.DataSource = dsUsers.Tables["Users"]; 
cmUsers = (CurrencyManager)cbxUsers.BindingContext[dsUsers.Tables["Users"]]; 
cbxUsers.DisplayMember = "Code"; 

这代码似乎工作。我可以滚动代码列表。此外,我可以开始手动编写代码,ComboBox将为我自动完成代码。

但是,我想在组合框的顶部放置一个标签,以显示当前所选用户代码的名称和姓氏。

我行的,虽然是这样的:“所以,我需要找到的代码组合框并在这事件中,我将获得当前的DataRow的变化之后,将触发一个事件...”

我正在浏览组合框的事件,尝试了其中的很多,但没有成功。

例如:

private void cbxUsers_SelectionChangeCommitted(object sender, EventArgs e) 
{ 
if (cmUsers != null) 
{ 
    DataRowView drvCurrentRowView = (DataRowView)cmUsers.Current; 
    DataRow drCurrentRow = drvCurrentRowView.Row; 
    lblNameSurname.Text = Convert.ToString(drCurrentRow["Name"]) + " " + Convert.ToString(drCurrentRow["Surname"]); 
} 
} 

这给我一个奇怪的结果。首先当我通过鼠标滚动滚动它不会返回我期望获得的行。例如,在JD上,它向我展示了“Mike Smith”,在MS上,它向我展示了“John Doe”,并在UP上向我展示了“Mike Smith”! 另一个问题是,当我开始键入ComboBox并按下Enter键时,它不会触发事件。

然而,一切正常,当我以这种方式将数据绑定到lblNameSurname.Text:

lblNameSurname.DataBindings.Add("Text", dsusers.Tables["Users"], "Name"); 

的这里的问题是,我只能绑定一列,我想有两个。我不想使用两个标签(一个显示姓名和其他显示姓氏)。

那么,我的问题有什么解决办法?

另外,我有一个问题与ComboBox中的数据选择有关。现在,当我在组合框中输入内容时,它允许我输入列表中不存在的字母。 例如,我开始键入“J”,而不是以“D”结束,所以我会有“JD”,我键入“Jsomerandomtexthere”。 Combobox将允许,但这样的项目不在列表中。换句话说,我想要组合框来防止用户输入不在代码列表中的代码。

回答

2

刚我自己做了一个测试,我认为你可能在寻找的是错误的事件(甚至可能是错误的对象)。

我只是尝试将事件添加到CurrencyManager对象(cmUsers)的PositionChanged处理程序,并且它完全按照预期工作。我遇到的唯一问题是第一次加载它时,它不会触及PositionChanged,因此第一个项目永远不会被绑定到标签(我确信有一个更简单的修复方法)。 http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingmanagerbase.positionchanged.aspx

然一个小测试,看看哪些事件得到了最早被解雇,而且似乎PositionChanged之前发射的SelectionChangeCommitted事件,这意味着CurrencyManager的还没有更新它的内部位置呢,太行:

DataRowView drvCurrentRowView = (DataRowView)cmUsers.Current; 

拉错了DataRow。

忘记你的第二个问题。大多数控件不处理按键,所以你应该做的是绑定OnKeyDown或OnKeyPress事件来运行你想要的任何函数(找到与类型化对象相关联的索引[即FindString()],并将ComboBox.SelectedIndex属性设置为找到的索引,否则闪烁警告)。例如:

if(e.KeyCode == Keys.Enter) 
{ 
    int indx; 
    cmbBox.SelectAll(); 
    if((indx = FindString(cmbBox.SelectedText)) != -1) 
     cmbBox.SelectedIndex = indx; 
    else 
     // Some warning 
} 

编辑 阅读您的意见后,我想出一个更简单的方法来做验证。在ComboBox的“KeyPress”事件中,使用以下代码:

if(e.KeyChar != (char)Keys.Enter) 
{ 
    if(cmbBox.FindString(cmbBox.Text + e.KeyChar) == -1) 
    { 
     e.Handled= true; 
    } 
} 

没有大惊小怪,没有错误。由于我们仅限于列表中的项目,因此在按Enter键时我们不需要处理,因为它应该自动更改所选项目(但是,运行某些验证以确保它是适当的cAsE,或者只是在Enter键上手动更改SelectedIndex属性)。 不过,希望这能帮助别人。

+0

感谢您的关注,我会再次审视这个问题。 – Wodzu 2010-07-21 13:41:50

+0

你有权利。你让我再一次考虑这一点,并且我添加了一个bindingSource(显示CurrencyManager)事件。通过他们,我已经能够完成任务。 – Wodzu 2010-07-25 12:58:35

0

关于第二个问题的两个方面,我通常做的是之前我离开表单处理Validating事件组合框(和禁用继续按钮或抛出了一个错误信息)或设置ComboBox.DropDownStyleComboBoxStyle.DropDownList

+0

谢谢斯科特。我认为这些解决方案都不适合我。据我所知,更改DropDownList的样式将禁用键入,我不希望这样。我只想限制输入到列表中的东西上。但我认为我可以在KeyPress事件中编写自己的验证,并且没问题。 – Wodzu 2010-05-06 22:39:04

0

那么,你可以改变你的SQL来获取名字和姓氏作为一列,然后绑定一次该列。另外,我会将组合和标签放在Ajax更新面板中。

关于验证:要在客户端验证您需要提前在客户端提供所有可能的值,或者为每个字符回发并使用(这可能不是一个好主意 - 杀死服务器)SQL:

SELECT code FROM TABLE WHERE code LIKE @x + '%' 

自动完成框是一个可以接受的选项吗?举个例子,看看jQuery的自动完成框。

0

尝试以下操作:

手动创建绑定对象,所以你必须对它的引用。使用Binding对象绑定到您的ComboBox的SelectedItem属性。我认为这应该让你选择DataRow。将该绑定对象添加到标签的DataBindings集合中。

处理Binding.Format事件(或者它可能是Parse-无法完全记住哪个事件适用于在哪个方向进行绑定时),并使用在事件args对象中接收的DataRow对象形成一个合适的名称字符串,其中包含姓和名。您需要将EventArgs的某些其他属性设置为该字符串。

您还可能需要使用Binding类的FormattingEnabled属性 - 自从我上次做这件事以来已经有一段时间了,我只记得它有点棘手。

见的分析和格式化事件的文档:http://msdn.microsoft.com/en-us/library/system.windows.forms.binding_events.aspx

0

通常当你改变你的选择和要将焦点之外下拉的像点击之外或按tab键下拉菜单中选择指标变化的事件发生...

如果你需要立即触发它,你应该寻求一些其他事件或通过调用事件的JavaScript onchange事件,等...