通过DatagridView的DataSource进行数据绑定时,正在设置DataGridViewRow.Tag的值



我试图在数据绑定时为DataGridViewRow.Tag设置一个值,但我不知道如何做到?

我试过使用DataRow row = table.NewRow();,但行没有标记。

binding DataGridView为表时,如何设置DataGridViewRow.Tag的值(例如(?或者这是不可能的?

第1版:

这是我正在使用的代码:

var table = new DataTable();
table.Columns.Add("Title", typeof(string));
table.Columns.Add("URL", typeof(string));
table.Columns.Add("Read Later", typeof(bool));
foreach (XElement node in nodes)
{
Helper.CheckNode(node);
var id = node.Attribute("id").Value;
var url = node.Element("path").Value;
var comment = node.Element("title").Value;
var readlater = node.Attribute("readLater")?.Value.ToString() == "1";
var row = table.NewRow();
row.ItemArray = new object[] { url, comment, readlater };

table.Rows.Add(row);//Edit2
}
dataGridView1.DataSource = table;

我正在尝试为行设置一个标签,以便在CellClick事件中使用它:

var cRow = dataGridView1.Rows[e.RowIndex];
var id = cRow.Tag.ToString();

将数据与显示方式分开

在使用DataGridView时,直接访问单元格和列很少是一个好主意。使用DataGridView.DataSource要容易得多。

在现代编程中,有一种趋势是将数据(=模型(与数据的显示方式(=视图(分开。要将这两项粘合在一起,需要一个适配器类,它通常被称为视图模型。简称这三个项目称为MVVM。

使用DataGridView.DataSource显示数据

显然,如果操作员点击一个单元格,你想读取该单元格行的标签值,以获得一些额外的信息,一些Id。

此显示的行是某些数据的显示。显然,这个数据的部分功能是访问这个Id。你不应该把这个信息放在视图中,你应该把它放在模型中。

class MyWebPage                        // TODO: invent proper identifier
{
public int Id {get; set;}
public string Title {get; set;}
public string Url {get; set;}
public bool ReadLater {get; set;}
... // other properties
}

显然,您有一种方法可以从nodes序列中获取要显示的数据。将获取数据(=模型(与显示数据(=视图(分开:

IEnumerable<MyWebPage> FetchWebPages(...)
{
...
foreach (XElement node in nodes)
{
Helper.CheckNode(node);
bool readLater = this.CreateReadLater(node);
yield return new MyWebPage
{
Id = node.Attribute("id").Value,
Url = node.Element("path").Value,
Title = node.Element("title").Value,
ReadLater = this.CreateReadLater(node),
};
}
}

我不知道节点"中有什么;ReadLater";,显然你知道如何将其转换为布尔值。

bool CreateReadLater(XElement node)
{
// TODO: implement, if null return true; if not null ...
// out of scope of this question
}

对于要显示的每个属性,都要创建一个DataGridViewColumn。属性DataPropertyName定义应在列中显示的属性。如果标准ToString不足以正确显示值,例如,定义小数点后的位数,或将负值涂成红色,请使用DefaultCellStyle。

您可以使用visualstudio设计器来完成此操作,也可以在构造函数中完成此操作:

public MyForm
{
InitializeComponents();
this.dataGridViewColumnTitle.DataPropertyName = nameof(MyWebPage.Title);
this.dataGridViewColumnUrl.DataPropertyName = nameof(MyWebPage.Url);
...
}

您不想显示Id,因此没有相应的列。

现在要显示数据,您所要做的就是将列表分配给数据源:

this.dataGrieViewWebPages.DataSource = this.FetchWebPages().ToList();

这只是显示。如果操作员可以更改显示的值,并且您希望访问更改后的值,则应该将项放在实现接口IBindingList的对象中,例如,使用类(惊奇!(BindingList<T>:

private BindingList<MyWebPage> DisplayedWebPages
{
get => (BindingList<MyWebPage>)this.dataGrieViewWebPages.DataSource;
set => this.dataGrieViewWebPages.DataSource = value;
}

初始化:

private void DisplayWebPages()
{
this.DisplayedWebPages = new BindingList<MyWebPage>(this.FetchWebPages.ToList());
}

还有普雷斯托!将显示所有网页。操作员所做的每一项更改:添加/删除/编辑行都会在DisplayedWebPages中自动更新。

如果您想访问当前选择的网页:

private MyWebPage CurrentWebPage =>(MyWebPage)this.dataGrieViewWebPages.CurrentRow?.DataBoundItem;
private IEnumerable<MyWebPage> SelectedWebPages =>
this.dataGrieViewWebPages.SelectedRows
.Cast<DataGridViewRow>()
.Select(row => row.DataBoundItem)
.Cast<MyWebPage>();

现在,很明显,每当操作员单击一个单元格时,您都希望对显示在单元格行中的网页的Id进行处理。

  • 视图:显示的单元格和行
  • ViewModel:操作员单击单元格时反应
  • 模型必须执行的操作

点击细胞反应:获取Id

我们已经处理了上面的视图。ViewModel是事件处理程序:

void OnDatGridViewCellClicked(object sender, DataGridViewCellEventArgs e)
{
// use the eventArgs to fetch the row, and thus the WebPage:
MyWebPage webPage = (MyWebPage)this.dataGridViewWebPages.Rows[e.RowIndow].DataBoundItem;
this.ProcessWebPage(webPage);
}

ProcessWebPage通常是Model类中的一个方法:

public void ProcessWebPage(MyWebPage webPage)
{
// Do what you need to do if the operator clicks the cell, for example:
int webPageId = webPage.Id;
...
}

结论:模型与视图分离的优点

顺便问一下,你看到所有ViewModel方法都是一行代码吗?只有模型方法FetchWebPages和ProcessWebPage包含几行。

因为您将视图与模型分离,所以对模型或视图的更改将相当简单:

  • 如果您想以Json格式存储数据,或者将数据存储在数据库中而不是XML中,则视图不会更改
  • 如果你不想在点击单元格时做出反应,但在点击按钮"确定"时,你的模型不会改变。如果您决定显示更多或更少的列,则模型也不必更改
  • 由于您将模型与视图分离,因此可以在没有窗体的情况下对模型进行单元测试。您也可以使用仅填充测试值的模型来测试视图

相关内容

  • 没有找到相关文章

最新更新