如何将复选框列表与我的 class 中的属性绑定?

How to bind a checkboxlist with properties in my class?

我正在创建一个有两种形式的应用程序,一种是为了了解我选择的是哪个文件,第二种只是为了之前做一个过滤器,这意味着你可以选择你想在这个里面看到哪些属性文件。我有一个复选框列表和 class 我的属性。

我的第一个表单中还有一个按钮:

foreach (var item in ds)
            {
                DataGridViewRow row = new DataGridViewRow();

                fileListDataGridView.Rows.Add(
                item.Path,
                item.PatientName,
                item.PatientID);
            }
           

我不确定这是从 DataGridWiev 中的列表添加数据的正确方法,但现在我有了这个解决方案。因为它只是在列表末尾添加了一个新项目。

问题是我在第二种形式中选中了 checkedListBox,我需要以某种方式将它与我的属性绑定。

属性:

public string Path { get; set; }
public string PatientName { get; set; }
public string PatientID { get; set; }

当您单击带有患者姓名的复选框时,这意味着您将在第一个表格中获得只有此 属性 的信息。我知道当我们制作一个 checkedListBox 时,我们在那里也有一个索引,但是我怎样才能得到这个索引并将它与我的 prop 绑定?

不熟悉 DataGridView 编程的人倾向于 fiddle 使用 DataGridView 的行和单元格。这很麻烦,难以理解,难以重用并且很难进行单元测试。

使用数据绑定要容易得多。

显然您想在 DataGridView 中显示 Patient 的几个属性。

class Patient
{
    public int Id {get; set;}
    public string Name {get; set;}
    public string Path {get; set;}
    ... // other properties?
}

您使用 visual studio 添加了 DataGridView 和要显示的列。在您的表单的构造函数中:

public MyForm()
{
    InitializeComponent();

    // assign Patient properties to the columns:
    this.columnId.DataPropertyName = nameof(Patient.Id);
    this.columnName.DataPropertyName = nameof(Patient.Name);
    this.columnPath.DataPropertyName = nameof(Patient.Path);
    ... // etc.
}

在您的表单中的某处,您有一个方法来获取必须显示的患者:

IEnumerable<Patient> FetchPatientsToDisplay()
{
    ... // TODO: implement; out-of-scope of this question
}

为了显示患者,我们使用 BindingList:

BindingList<Patient> DisplayedPatients
{
    get => (BindingList<Patient>)this.dataGridView1.DataSource;
    set => this.dataGridView1.DataSource = value;
}

现在在加载表单时填充 DataGridView:

void OnFormLoading(object sender, ...)
{
    this.ShowPatients();
}

void ShowPatients()
{
    this.DisplayedPatients = new BindingList<Patient>(this.FetchPatientsToDisplay().ToList());
}

就是这样!显示患者;如果允许,操作员可以添加/删除/编辑患者。完成编辑后,他通过按 OKApply Now 按钮通知程序:

void ButtonOk_Clicked(object sender, ...)
{
    // Fetch the edited Patients:
    ICollection<Patient> editedPatients = this.DisplayedPatients;
    // find out which patients are changed and process them
    this.ProcessPatients(editedPatients);
}

所以您不需要自己添加/删除行。通常操作员会这样做。如果默认患者不足以显示,请使用事件 BindingList.AddningNew:

void OnAddingNewPatient(object sender, AddingNewEventArgs e)
{
    // create a new Patient and give it the initial values that you want
    e.NewObject = new Patient()
    {
        Id = 0,   // zero: this Patient has no Id yet, because it is not added to the database yet
        Name = String.Empty,
        Path = String.Empty,
    }
}

也许以下属性可能有用:

Patient CurrentPatient => (Patient) this.dataGridView1.CurrentRow?.DataBoundItem;

如果允许多选:

IEnumerable<Patient> SelectedPatients = this.dataGridView1.SelectedRows
    .Cast(row => row.DataGridViewRow)
    .Select(row => row.DataBoundItem)
    .Cast<Patient>();

换言之:将datagridView 中的每个选定行解释为DataGridViewRow。从每个 DataGridViewRow 获取数据绑定到它的项目。我们知道这是一个 Patient,所以我们可以将它转换为一个 Patient。