WPF 数据网格获取选定的单元格值
本文关键字:单元格 获取 数据 数据网 网格 WPF | 更新日期: 2023-09-27 18:34:09
我想在数据网格中获取所选单元格的值,请任何人告诉如何做到这一点。 我使用了 选择单元格更改事件 ,我该怎么做?
dataGrid1.CurrentCell
当我遇到这个问题时,我是这样处理的:我创建了一个DataRowView
,获取了列索引,然后在行的ItemArray
中使用它
DataRowView dataRow = (DataRowView)dataGrid1.SelectedItem;
int index = dataGrid1.CurrentCell.Column.DisplayIndex;
string cellValue = dataRow.Row.ItemArray[index].ToString();
请参阅 MSDN 上的 DataGrid 类页。从该页面:
选择
默认情况下,当用户单击 DataGrid 中的单元格时,将选择整行,并且用户可以选择多行。可以设置 SelectionMode 属性以指定用户是否可以选择单元格、整行或同时选择两者。设置 SelectionUnit 属性以指定是可以选择多行或多单元格,还是只能选择单行或单个单元格。
可以获取有关从"选定单元格"属性中选择的单元格的信息。您可以在 SelectedCellsChanged 事件的 SelectedCellsChangedEventArgs 中获取有关其选择已更改的单元格的信息。调用 SelectAllCells 或 UnselectAllCells 方法以编程方式选择或取消选择所有单元格。有关更多信息,请参见 DataGrid 控件中的默认键盘和鼠标行为。
我已经为您添加了相关属性的链接,但现在我没有时间了,所以我希望您可以按照链接获取解决方案。
只选择一个单元格,则像这样获取选定的单元格内容
var cellInfo = dataGrid1.SelectedCells[0];
var content = cellInfo.Column.GetCellContent(cellInfo.Item);
此处的内容将是您选择的单元格值
如果你选择多个单元格,那么你可以这样做
var cellInfos = dataGrid1.SelectedCells;
var list1 = new List<string>();
foreach (DataGridCellInfo cellInfo in cellInfos)
{
if (cellInfo.IsValid)
{
//GetCellContent returns FrameworkElement
var content= cellInfo.Column.GetCellContent(cellInfo.Item);
//Need to add the extra lines of code below to get desired output
//get the datacontext from FrameworkElement and typecast to DataRowView
var row = (DataRowView)content.DataContext;
//ItemArray returns an object array with single element
object[] obj = row.Row.ItemArray;
//store the obj array in a list or Arraylist for later use
list1.Add(obj[0].ToString());
}
}
我正在将 Rushi 的解决方案扩展到以下(这为我解决了难题(
var cellInfo = Grid1.SelectedCells[0];
var content = (cellInfo.Column.GetCellContent(cellInfo.Item) as TextBlock).Text;
如果SelectionUnit="Cell"
试试这个:
string cellValue = GetSelectedCellValue();
哪里:
public string GetSelectedCellValue()
{
DataGridCellInfo cellInfo = MyDataGrid.SelectedCells[0];
if (cellInfo == null) return null;
DataGridBoundColumn column = cellInfo.Column as DataGridBoundColumn;
if (column == null) return null;
FrameworkElement element = new FrameworkElement() { DataContext = cellInfo.Item };
BindingOperations.SetBinding(element, TagProperty, column.Binding);
return element.Tag.ToString();
}
似乎不应该那么复杂,我知道...
编辑:这似乎不适用于DataGridTemplateColumn
类型列。如果您的行由自定义类组成并且您分配了排序成员路径,您也可以尝试此操作:
public string GetSelectedCellValue()
{
DataGridCellInfo cells = MyDataGrid.SelectedCells[0];
YourRowClass item = cells.Item as YourRowClass;
string columnName = cells.Column.SortMemberPath;
if (item == null || columnName == null) return null;
object result = item.GetType().GetProperty(columnName).GetValue(item, null);
if (result == null) return null;
return result.ToString();
}
//Xaml Code
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Date, Converter={StaticResource dateconverter}, Mode=OneWay}" Header="Date" Width="100"/>
<DataGridTextColumn Binding="{Binding Path=Prescription}" Header="Prescription" Width="900"/>
</DataGrid.Columns>
//C# Code
DataRowView row = (DataRowView)grid1.SelectedItem;
MessageBox.Show(row["Prescription"].toString() + " " + row["Date"].toString());
由于 WPF 在 DataGrid 中提供绑定,因此这应该是相当透明的。但是,以下方法仅在您使用了 SQLDataAdapter 并提供指向 DataGridColoumns 的绑定路径时才有效。例如。假设上面的数据网格名为 grid1,它的自动生成列设置为 false,并使用绑定将列名绑定到 Headers。在这种情况下,我们使用类型为"DataRowView"的"row"变量并将选定的行存储在其中。现在,使用绑定路径,并引用所选行的各个列。希望这有帮助!干杯!
PS:如果选择单位="行",则有效
在进行逆向工程和一点反射的小精灵尘埃之后,可以在SelectedCells
(在任何时候(执行此操作,以获取所有(无论在一行或多行上选择(数据从一到多个选定单元格:
MessageBox.Show(
string.Join(", ", myGrid.SelectedCells
.Select(cl => cl.Item.GetType()
.GetProperty(cl.Column.SortMemberPath)
.GetValue(cl.Item, null)))
);
我仅在文本(字符串(字段上尝试过此操作,尽管 DateTime 字段应返回启动ToString()
的值。另请注意,SortMemberPath
与Header
不同,因此应始终提供适当的属性来反映。
<DataGrid ItemsSource="{Binding MyData}"
AutoGenerateColumns="True"
Name="myGrid"
IsReadOnly="True"
SelectionUnit="Cell"
SelectionMode="Extended">
我工作
object item = dgwLoadItems.SelectedItem;
string ID = (dgwLoadItems.SelectedCells[0].Column.GetCellContent(item) as TextBlock).Text;
MessageBox.Show(ID);
这是 2 种方法,可用于从所选行中获取值
/// <summary>
/// Take a value from a the selected row of a DataGrid
/// ATTENTION : The column's index is absolute : if the DataGrid is reorganized by the user,
/// the index must change
/// </summary>
/// <param name="dGrid">The DataGrid where we take the value</param>
/// <param name="columnIndex">The value's line index</param>
/// <returns>The value contained in the selected line or an empty string if nothing is selected</returns>
public static string getDataGridValueAt(DataGrid dGrid, int columnIndex)
{
if (dGrid.SelectedItem == null)
return "";
string str = dGrid.SelectedItem.ToString(); // Take the selected line
str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Delete useless characters
if (columnIndex < 0 || columnIndex >= str.Split(',').Length) // case where the index can't be used
return "";
str = str.Split(',')[columnIndex].Trim();
str = str.Split('=')[1].Trim();
return str;
}
/// <summary>
/// Take a value from a the selected row of a DataGrid
/// </summary>
/// <param name="dGrid">The DataGrid where we take the value.</param>
/// <param name="columnName">The column's name of the searched value. Be careful, the parameter must be the same as the shown on the dataGrid</param>
/// <returns>The value contained in the selected line or an empty string if nothing is selected or if the column doesn't exist</returns>
public static string getDataGridValueAt(DataGrid dGrid, string columnName)
{
if (dGrid.SelectedItem == null)
return "";
for (int i = 0; i < columnName.Length; i++)
if (columnName.ElementAt(i) == '_')
{
columnName = columnName.Insert(i, "_");
i++;
}
string str = dGrid.SelectedItem.ToString(); // Get the selected Line
str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Remove useless characters
for (int i = 0; i < str.Split(',').Length; i++)
if (str.Split(',')[i].Trim().Split('=')[0].Trim() == columnName) // Check if the searched column exists in the dataGrid.
return str.Split(',')[i].Trim().Split('=')[1].Trim();
return str;
}
我为此挣扎了很长时间!(使用 VB.NET(基本上,您可以获取所选单元格的行索引和列索引,然后使用它来访问该值。
Private Sub LineListDataGrid_SelectedCellsChanged(sender As Object, e As SelectedCellsChangedEventArgs) Handles LineListDataGrid.SelectedCellsChanged
Dim colInd As Integer = LineListDataGrid.CurrentCell.Column.DisplayIndex
Dim rowInd As Integer = LineListDataGrid.Items.IndexOf(LineListDataGrid.CurrentItem)
Dim item As String
Try
item = LLDB.LineList.Rows(rowInd)(colInd)
Catch
Exit Sub
End Try
End Sub
结束类
你也可以使用这个函数。
public static void GetGridSelectedView(out string tuid, ref DataGrid dataGrid,string Column)
{
try
{
// grid selected row values
var item = dataGrid.SelectedItem as DataRowView;
if (null == item) tuid = null;
if (item.DataView.Count > 0)
{
tuid = item.DataView[dataGrid.SelectedIndex][Column].ToString().Trim();
}
else { tuid = null; }
}
catch (Exception exc) { System.Windows.MessageBox.Show(exc.Message); tuid = null; }
}
我处于这种情况..并发现:
int ColumnIndex = DataGrid.CurrentColumn.DisplayIndex;
TextBlock CellContent = DataGrid.SelectedCells[ColumnIndex].Column.GetCellContent(DataGrid.SelectedItem);
并确保处理自定义列的模板
我愚蠢地找到了解决方案......
对我来说(VB(:
Dim string= Datagrid.SelectedCells(0).Item(0).ToString
Mohamed RT的想法是正确的,它对我有用。似乎唯一缺少的是显式强制转换为TextBlock。通过获取数据网格的 CurrentColumn.DisplayIndex,您可以定义要提取其值的确切单元格。当用户重新排列列时,这也适用于。这是我的代码:
int columnIndex = yourDataGrid.CurrentColumn.DisplayIndex;
TextBlock targetCell = (TextBlock)yourDataGrid.SelectedCells[columnIndex].Column.GetCellContent(yourDataGrid.SelectedItem);
并提取 TextBlock 的值:
MessageBox.Show("Target cell value is: " + targetCell.Text);
在我读到的所有答案中,这似乎是最简单和最有力的。非常感谢穆罕默德!
这是我解决问题的方法。这个解决方案留给我的唯一问题是空引用的可能性。
var Item = ((DataRowView)dataGrid.SelectedCells[0].Item)
.Row
.ItemArray[dataGrid.SelectedCells[0].Column.DisplayIndex];
如果您只想要选定行中固定单元格的值,则可以使用此更短的代码。
var Item = ((DataRowView)dataGrid.SelectedValue).Row.ItemArray[0];
不要忘记将项目转换为正确的类型。