我們有這樣一個場景,我們有一個包含DataGrid的頁面,現在我們想要從這個DataGrid獲取所有數據,但是沒有訪問它的基礎項源,也就是說,我們希望直接從數據源訪問數據DataGrid。這似乎很棘手,但並非不可能。我發現了很多文章,像這樣:DataGridHelper,和這個:Get WPF DataGrid row and cell,和許多其他的。它們基本上是一樣的:在另一個GetVisualChild函數的幫助下,在DataGrid上定義擴展方法來查找目標DataGridCell對象。但是,當我使用它時,我無法找到目標單元格。具體來說,DataGrid中的每一行對應於DataContext集合中的一個項目,假設它是「Employee」類型的集合,並且DataGrid的每一列都對應Employee類的一個屬性,例如Name,Gender ,年齡。現在我的問題是,上面提到的GetCell()函數總是找到一個DataGridCell,其中一個Employee對象作爲其內容(DataGridCell中Content的屬性),並且無論我給出的列索引如何,都無法進一步進入每個屬性它。 例如,在GetCell函數中,有一行: Dim cell As DataGridCell = DirectCast(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell)
, 其中演示者是一個DataGridCellsPresenter我得到了表示我選擇的行,並且一旦我給列索引,自然我期待它返回指定位置I的選定屬性的控制。但它不能按預期工作。任何幫助,將不勝感激!訪問WPF中DataGrid的單元格值?
0
A
回答
0
當你使用presenter.ItemContainerGenerator.ContainerFromIndex
時,你陷入了一個限制,它只能用於非虛擬化的項目,即在滾動視圖中顯示的行(加上滾動視圖限制上下的一些偏移行數)數據網格。
爲了您訪問所有單元格的值,您必須爲每行執行列級綁定。
訪問
DataGrid.Items
集合。這是項目的視圖,因此任何通過過濾標準或自定義分頁等隱藏的項目都將被排除。如果你不想那麼請撥打DataGrid.ItemsSource.Cast<object>().ToList()
。現在訪問數據網格的所有列,即
DataGrid.Columns
。假設它們是任何類型,但是DataGridTemplateColumn
,下面的步驟3將提取單元級別的值。對於模板列,您必須指定一些代表單元格整個模板的屬性值。我發現DataGridTemplateColumn.SortMemberPath
是一個很好的候選人。提取
DataGridTextColumn.Binding
,DataGridCheckBoxColumn.Binding
,DataGridComboBoxColumn.SelectedValueBinding
或DataGridComboBoxColumn.SelectedItemBinding
。然後對於步驟1中的每個項目,執行綁定以提取值。
代碼
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string gridContent = string.Empty;
foreach(var item in MyDataGrid.Items)
{
foreach (var column in MyDataGrid.Columns)
{
var textCol = column as DataGridTextColumn;
var checkCol = column as DataGridCheckBoxColumn;
var comboCol = column as DataGridComboBoxColumn;
var templateCol = column as DataGridTemplateColumn;
if (textCol != null)
{
var propertyName = ((Binding)textCol.Binding).Path.Path;
var value
= item.GetType().GetProperty(
propertyName).GetValue(
item,
new object[] {});
if (((Binding)textCol.Binding).Converter != null)
{
value
= ((Binding)checkCol.Binding).Converter.Convert(
value,
typeof(object),
((Binding)checkCol.Binding).ConverterParameter,
((Binding)checkCol.Binding).ConverterCulture);
}
gridContent = gridContent + "\t" + value.ToString();
}
if (checkCol != null)
{
var propertyName = ((Binding)checkCol.Binding).Path.Path;
object value
= item.GetType().GetProperty(
propertyName).GetValue(
item,
new object[] { });
if (((Binding)checkCol.Binding).Converter != null)
{
value
= ((Binding)checkCol.Binding).Converter.Convert(
value,
typeof(object),
((Binding)checkCol.Binding).ConverterParameter,
((Binding)checkCol.Binding).ConverterCulture);
}
gridContent = gridContent + "\t" + value.ToString();
}
if (comboCol != null)
{
var propertyName = string.Empty;
if (comboCol.SelectedValueBinding != null)
{
propertyName
= ((Binding)comboCol.SelectedValueBinding).Path.Path;
}
else if (!string.IsNullOrEmpty(comboCol.SelectedValuePath))
{
propertyName = comboCol.SelectedValuePath;
}
else if (!string.IsNullOrEmpty(comboCol.DisplayMemberPath))
{
propertyName = comboCol.DisplayMemberPath;
}
var value = item.GetType().GetProperty(
propertyName).GetValue(
item,
new object[] { });
if (comboCol.SelectedValueBinding != null
&& ((Binding)comboCol.SelectedValueBinding).Converter != null)
{
var bnd = (Binding)comboCol.SelectedValueBinding;
value
= bnd.Converter.Convert(
value,
typeof(object),
bnd.ConverterParameter,
bnd.ConverterCulture);
}
gridContent = gridContent + "\t" + value.ToString();
}
if (templateCol != null)
{
var propertyName = templateCol.SortMemberPath;
var value
= item.GetType().GetProperty(
propertyName).GetValue(
item,
new object[] { });
gridContent = gridContent + "\t" + value.ToString();
}
}
gridContent = gridContent + "\n";
}
MessageBox.Show(gridContent);
}
}
0
我意識到這是老話題,但我尋找一個簡單的解決方案,並終於找到了。以爲其他人可能喜歡簡單。以下示例通過指定的列搜索數據網格以獲得所需的值,如果找到則選擇該行。
private void dgSetRow(DataGrid dg, string sColHeader, int iFindValue)
{
foreach (DataRowView drv in dg.Items)
{
// compare value in datarow of view
if (iFindValue == (int)drv.Row[sColHeader])
{
// select item
dg.SelectedItem = drv;
dg.ScrollIntoView(drv);
}
}
}
相關問題
- 1. WPF datagrid - 編輯的單元格的值
- 2. 在javascript中訪問datagrid單元格
- 3. WPF訪問DataGrid行元素
- 4. WPF Toolkit DataGrid SelectionChanged獲取單元格值
- 5. WPF Datagrid單元格值編輯C#
- 6. WPF Datagrid讀取單元格值
- 7. WPF禁用DataGrid單元格
- 8. WPF Datagrid單元格爲空
- 9. 在WPF DataGrid中格式化單元格
- 10. wpf datagrid行中的小計單元格
- 11. 在DataGrid中編輯單元格(WPF)
- 12. 在WPF DataGrid中合併單元格
- 13. Wpf datagrid更新datacontext上datagrid單元格值更改
- 14. 如何從WPF DataGrid中讀取單元格中的值?
- 15. WPF datagrid單元格顏色取決於preivous單元值
- 16. WPF DataGrid,在ColumnTemplate的綁定中訪問DataGrid外的元素
- 17. 如何從WPF中的datagrid獲取單元格的值?
- 18. WPF:帶有blanck單元格的DataGrid
- 19. 如何從WPF 4.0 Datagrid中的特定單元格獲取值?
- 20. WPF Datagrid從某一行的單元格中選擇一個值
- 21. 如何確定DataGrid中選定單元格的值? (WPF)
- 22. 如何獲取WPF中Datagrid的單元格數據值?
- 23. 將datagrid行顏色綁定到WPF中的單元格值
- 24. wpf爲DataGrid中的單元格着色基於值
- 25. 使元素可見後訪問WPF DataGrid
- 26. 根據單元格值的比較更改WPF DataGrid單元格字體
- 27. 檢索DataGrid單元格值
- 28. 訪問ListView的網格單元格值
- 29. 訪問WPF的DataGrid ContainerStyle
- 30. 以編程方式在WPF中更改DataGrid單元格值
感謝您的幫助!這幾乎清除了我的問題。但是我的情況是,我現在可以獲得DataGrid背後的屬性值,但不幸的是,這不是我想要的。仍然以我的Employee爲例,現在我可以獲得Name,Gender,Age的屬性值,這可能是一些類實例。例如,類名稱和性別。但我想要的是在DataGrid的TextBlock中顯示的文本。例如,我可能會選擇在「名稱」單元格中顯示名字,因此僅獲取名稱實例是不夠的。我想訪問單元格的原因(待續) – tete
TextBlock值(而不是屬性本身)是,我在每個DataGrid單元格中使用了很多自定義的TextBlock,它根據用戶的選擇進行格式設置。在運行時沒有簡單的方法來獲得這種格式化信息。或者我可以說我們希望避免它,因爲只要格式化的值已經存在於某處,它就有點多餘。例如,用戶可以設置顯示員工姓名的首字母,我們自定義的TextBlock已經顯示了這些姓名的首字母。所以我很自然地想知道這些縮寫,而不知道用戶選擇了什麼樣的格式。 – tete
我現在猜測我需要做的是通過所有存儲我們定製的TextBlock信息的Visuals,並且我可以直接獲取文本值,並且可能還需要我也需要的顏色信息。有沒有辦法做到這一點?再次感謝,我知道我可能已經問太多了:) – tete