【发布时间】:2026-02-23 00:05:01
【问题描述】:
我要求 new 和 deleted 行在 DataGridView 中不可见。我已经能够隐藏已删除的行,尽管不是以理想的方式。我无法正确隐藏新行,但仍然能够更改包含更多信息的详细信息组框中的绑定对象。这让我怀疑我解决这个问题的方式完全错误(另一个迹象是我搜索了很多,但找不到任何特别像我的情况的东西)。
目前的方法
我有一个绑定到BindingSource 的DataGridView。此 BindingSource 的 DataSource 目前是 BindingList<T>(但我尝试过其他的,例如 DataTable 和 DataView,并使用 IBindingListView 的自定义实现)。此外,一组控件(TextBoxes、ComboBoxes 等)绑定到 Current BindingSource 对象(参见代码下方的示例屏幕截图)。绑定的数据来自 WCF 服务,而不是来自数据库。
internal enum PersonState
{
// New rows that have not been "added" yet. Hide from UI.
New,
// New rows that have been "added". These should be saved to the server
Added,
// Altered rows. These should be updated on the server
Edited,
// Deleted rows. Hide from UI and delete from server when saving.
Deleted,
// Do nothing
Unchanged
}
public class Person : INotifyPropertyChanged
{
// the following properties have code to raise PropertyChanged
public string Name { get; set; }
public DateTime BirthDate { get; set; }
internal PersonState State { get; set; }
}
public void NewPersonButton_Click()
{
var person = new Person();
person.State = PersonState.New;
personList.Add( person );
}
现在,来自示例screenshot;如果用户单击“新建”,则Person 类的新实例将添加到支持BindingSource 的BindingList<T>。此时他们希望将行隐藏在DataGridView 中(状态为New),但用户应该能够使用详细信息组框更改值。一旦用户满意(并且信息通过验证),用户可以单击“添加”。只有在这一步之后,他们才想看到DataGridView 中的行(状态更改为Added)。
经过测试的方法
我已经测试了实现一个自定义的 IBindingListView,它将过滤底层集合(过滤状态等于 New 或 Deleted 的任何 Person 对象)。但是,这似乎可以防止使用详细信息组框进行修改。我尝试了几种方法,例如https://blogs.msdn.microsoft.com/winformsue/2008/05/19/implementing-multi-column-filtering-on-the-ibindinglistview/
我已经使用 DataGridView.Rows[i].Visible = false 测试了隐藏行,并手动跟踪哪些行应该被隐藏/可见。这与自定义 IBindingListView 具有相同的结果,因为无法将隐藏行设置为当前行。这可以防止编辑详细信息组框中的信息。
我没有看到任何使用直接绑定来实现此目的的方法。我想我要问的是;有没有人使用绑定实现了这样的目标?有人对替代方法有任何建议吗?
【问题讨论】:
-
为什么在点击
New时不为NewPerson创建一个属性,但不在用户点击Add之前将其添加到列表中? -
@OhBeWise 恐怕我必须做这样的事情。澄清;这意味着我必须在编辑这个“新”人时禁用组框中所有控件的绑定,并在用户单击“添加”或用户选择不同的行后重置绑定?
-
如果您将 GroupBox 字段绑定到当前行,那么是的,这可能不像我想象的那么简单。
标签: c# winforms data-binding datagridview bindingsource