【问题标题】:Binding a TextBox to a ListBox SelectedItem将 TextBox 绑定到 ListBox SelectedItem
【发布时间】:2019-12-05 12:22:42
【问题描述】:

我目前正在尝试实现一个相对简单的数据管理应用程序。

我有一个班级Member 和一个BindingList<Member> membersList,还有一个ListBox和一些TextBoxes。

ListBox 绑定到membersList

现在,理想情况下,我想将TextBoxes 绑定到ListBox.SelectedItem,以便用户在ListBox 中选择的任何元素,当他们编辑TextBox 时,membersList 中的元素都会更新.

我尝试将TextBoxes 绑定到ListBox.SelectedItem,但这使得Binding 成为ListBox.SelectedItem 在绑定创建时引用的实际元素,而不是@ 中选择的任何项目987654337@.

firstNameTextBox.DataBindings.Add(new Binding("Text",
membersList.SelectedItem, "firstName", false,
DataSourceUpdateMode.OnPropertyChanged));

我实际上已经通过在membersList_SelectedIndexChanged(object sender, EventArgs e) 事件处理程序中为TextBoxes 清除和重新创建Bindings 解决了这个问题,但这感觉非常“hacky”,我怀疑还有一个更标准的解决方案。

我的另一个想法是将Bindings 设置为Member temporaryMember,在membersList_SelectedIndexChanged(object sender, EventArgs e) 事件处理程序中设置为ListBox.SelectedItem,但随后我必须手动将更改写入相应的项目在membersList 这也让我觉得这不是最佳解决方案。

有没有办法让Binding 动态化,也就是说,在创建时,我向它表明DataSource 正在改变?

还是一种标准方式来更改Bindings 数据源而不删除它并创建一个新数据源? (或者这实际上是最佳实践?)

(要提的另一件事:我是 C# 中 Bindings 的新手,在搜索解决方案时,我发现显然有两个不同的类,一个在 System.Windows.Data 命名空间中,另一个在 System.Windows.Forms 命名空间中.我想我正在使用后者的类。也许我应该使用另一个?)

【问题讨论】:

  • 我尝试将 TextBoxes 绑定到 ListBox.SelectedItem,但这使得绑定到 ListBox.SelectedItem 在绑定创建时引用的实际元素,而不是选择的任何项目在 ListBox 中。 这是什么意思? ListBox中选中的项目是SelectedItem
  • ListBox 具有对双向数据绑定的内置支持。使用 BindungList<T> 作为 T 实现 InotifyPropertyChanged 的数据源。请查看this post 了解更多信息。
  • @RezaAghaei 是的,但是当ListBox.SelectedItem发生变化时,Binding的DataSource没有变化。
  • 你能验证绑定吗? membersList.SelectedItem, "firstName" 似乎绑定到源 membersList.SelectedItem 中的属性 firstName,它看起来不对...
  • 正如 Reza Aghaei 所说,还将BindingList 设置为BindingSource 的数据源。 TextBoxes 只需要一个Binding 设置为BindingSource,当ListBox 中的某个项目被选中时,TextBoxes 会自动更新。此外,当BindingList 的成员被更改/修改时。如果 BindingList 的某个项目发生更改,则 ListBox 不会更新当前的 ListItem,但如果发生这种情况,您只需调用 [BindingSource].ResetCurrentItem();

标签: c# .net winforms binding


【解决方案1】:

如 cmets 中所述,将 BindingList(或 DataTable)与 BindingSource 相关联可以带来一些有趣的好处。

BindingList 的元素之一被修改或新元素添加到列表中时,所有绑定控件都会自动更新。

您可以使用MovePrevious()MoveNext()MoveFirst()MoveLast() 方法来导航BindingList 中的元素(其他有用的方法和事件可用,请参阅有关 BindingSource 功能的文档)。

这里,BindingList<T>(其中T 是下面显示的Member 类)被设置为BindingSource 的DataSource。两者都是Form类的Fields,可以根据需要进行修改。
然后将 BindingSource 用作 ListBox 的 DataSource。

然后使用 BindingSource 将两个 TextBox 控件的 Text 属性绑定到 Member 类的属性之一。这样,Text 属性设置为 BindingList 的当前项。所有控件都同步

txtMemberName.DataBindings.Add(new Binding("Text", membersSource, 
    "FirstName", false, DataSourceUpdateMode.OnPropertyChanged));
txtMemberLastName.DataBindings.Add(new Binding("Text", membersSource, 
    "LastName", false, DataSourceUpdateMode.OnPropertyChanged));

这就是它的工作原理,在实践中:

注意,当修改TextBox的Text时,ListBox的当前Item会实时更新。

BindingList<Member> members = null;
BindingSource membersSource = null;

public partial class frmMembers : Form
{
    public frmMembers() {
        InitializeComponent();
        InitializeDataBinding();
    }

    private void InitializeDataBinding()
    {
        members = new BindingList<Member>();
        membersSource = new BindingSource(members, null);

        lstBoxMembers.DataSource = membersSource;
        txtMemberName.DataBindings.Add(new Binding("Text", membersSource, 
            "FirstName", false, DataSourceUpdateMode.OnPropertyChanged));
        txtMemberLastName.DataBindings.Add(new Binding("Text", membersSource, 
            "LastName", false, DataSourceUpdateMode.OnPropertyChanged));
    }

    private void btnAddMember_Click(object sender, EventArgs e)
    {
        var frmNew = new frmNewMember();
        if (frmNew.ShowDialog() == DialogResult.OK && frmNew.newMember != null) {
            members.Add(frmNew.newMember);
        }
    }

    private void btnMovePrevious_Click(object sender, EventArgs e)
    {
        if (membersSource.Position > 0) {
            membersSource.MovePrevious();
        }
        else {
            membersSource.MoveLast();
        }
    }

    private void btnMoveNext_Click(object sender, EventArgs e)
    {
        if (membersSource.Position == membersSource.List.Count - 1) {
            membersSource.MoveFirst();
        }
        else {
            membersSource.MoveNext();
        }
    }
}

新会员表格示例:

public partial class frmNewMember : Form
{
    public Member newMember;

    private void btnSave_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(txtMemberName.Text) || 
            string.IsNullOrEmpty(txtMemberLastName.Text)) return;
        newMember = new Member(txtMemberName.Text, txtMemberLastName.Text);
    }
}

示例成员类:

[Serializable()]
public class Member
{
    public Member() { }
    public Member(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public override string ToString() => $"{this.FirstName} {this.LastName}";
}

【讨论】:

    猜你喜欢
    • 2020-10-22
    • 1970-01-01
    • 2010-12-26
    • 2011-01-02
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多