在 DataGrid WPF 中获取选定的行项
Posted
技术标签:
【中文标题】在 DataGrid WPF 中获取选定的行项【英文标题】:Get selected row item in DataGrid WPF 【发布时间】:2011-04-24 05:41:06 【问题描述】:我有一个DataGrid
,绑定到数据库表,我需要在DataGrid
中获取选中行的内容,例如我想在MessageBox
中显示选中行的内容。
DataGrid
的示例:
所以,如果我选择第二行,我的 MessageBox
必须显示类似:646 Jim Biology。
【问题讨论】:
【参考方案1】:你的前台代码:
设置你的模型命名空间xmlns:viewModel="clr-namespace:CPL3_workstation.MVVM.ModelViews.Tables"
设置xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
,因为d:DataContext="d:DesignInstance...
<DataGrid d:DataContext="d:DesignInstance viewModel:TestViewModel, IsDesignTimeCreatable=True"
ItemsSource="Binding Rows"
SelectedItem="Binding Selector">
<DataGrid.Columns>
<DataGridTextColumn
Binding="Binding Content1"
Header="Столбец 1" />
<DataGridTextColumn
Binding="Binding Content2"
Header="Столбец 2" />
<DataGridTextColumn
Binding="Binding Content3"
Header="Столбец 3" />
</DataGrid.Columns>
</DataGrid>
您的ViewModel
和下面的Model
:
namespace CPL3_workstation.MVVM.ModelViews.Tables
public class TestViewModel
public IEnumerable<TestModel> Rows get; set;
public TestModel Selector
get => selector;
set => selector = value;
private TestModel selector;
public TestViewModel()
Rows = new List<TestModel>
new TestModel Content1 = "one", Content2 = "two", Content3 = "three" ,
new TestModel Content1 = "one", Content2 = "two", Content3 = "three" ,
new TestModel Content1 = "one", Content2 = "two", Content3 = "three" ,
new TestModel Content1 = "one", Content2 = "two", Content3 = "three"
;
public class TestModel
public string Content1 get; set;
public string Content2 get; set;
public string Content3 get; set;
如您所见,SelectedItem
绑定到模型类型的 Selector
属性。
【讨论】:
感谢您翻译答案,现在全球社区可以从您的知识和经验中受益。欢迎来到 SO!【参考方案2】:我得到了这样的东西:
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
DataGrid dg = (DataGrid)sender;
DataRowView selectedRow = dg.SelectedItem as DataRowView;
if(selectedRow != null)
txtXXX.Text = selectedRow["xxx"].ToString();
txtYYY.Text = selectedRow["yyy"].ToString();
txtZZZ.Text = selectedRow["zzz"].ToString();
【讨论】:
【参考方案3】:您可以使用SelectedItem
属性来获取当前选定的对象,然后您可以将其转换为正确的类型。例如,如果您的 DataGrid
绑定到 Customer
对象的集合,您可以这样做:
Customer customer = (Customer)myDataGrid.SelectedItem;
或者,您可以将SelectedItem
绑定到您的源类或ViewModel
。
<Grid DataContext="MyViewModel">
<DataGrid ItemsSource="Binding Path=Customers"
SelectedItem="Binding Path=SelectedCustomer, Mode=TwoWay"/>
</Grid>
【讨论】:
第二个正是我想要的。谢谢! 如何从给定的替代方式获取数据? 第二个效果很好,补充一点可能对像我这样刚开始使用 wpf 的人有所帮助。在这个问题中,我们正在查看类 Customer。如果您没有为行定义类 DataRowView 作为 System.Data 中的数据类型。【参考方案4】:这里有很多可能适用于特定上下文的答案,但我只是试图获取所选行中第一个单元格的文本值。虽然这里接受的答案对我来说是最接近的,但它仍然需要创建一个类型并将行转换为该类型。我一直在寻找一个更简单的解决方案,这就是我想出的:
MessageBox.Show(((DataRowView)DataGrid.SelectedItem).Row[0].ToString());
这给了我所选行中的第一列。希望这对其他人有帮助。
【讨论】:
当然这是个人喜好问题,但我个人更喜欢接受的答案,因为它基于标准 API 并且更易于阅读Customer customer = (Customer)myDataGrid.SelectedItem;
— 一条线解决方案,清晰和平原。没有(((
,没有索引Row[0]
,没有ToString()
——太多的额外操作无法通过一个命令获得API给你的东西——SelectedItem
。
这是假设您有一个“客户”类。如果您的 DataGrid 是从数据库查询中填充的,但 DataGrid 中的行没有特定的类,则接受的答案不起作用(除非我遗漏了什么)。也许对我来说更好的解决方案是创建这样一个类,但对于我不认为自己重用的东西,这似乎是多余的。【参考方案5】:
@Krytox 用 MVVM 回答
<DataGrid
Grid.Column="1"
Grid.Row="1"
Margin="10" Grid.RowSpan="2"
ItemsSource="Binding Data_Table"
SelectedItem="Binding Select_Request, Mode=TwoWay" SelectionChanged="DataGrid_SelectionChanged"/>//The binding
#region View Model
private DataRowView select_request;
public DataRowView Select_Request
get return select_request;
set
select_request = value;
OnPropertyChanged("Select_Request"); //INotifyPropertyChange
OnSelect_RequestChange();//do stuff
【讨论】:
【参考方案6】:您还可以:
DataRowView row = dataGrid.SelectedItem as DataRowView;
MessageBox.Show(row.Row.ItemArray[1].ToString());
【讨论】:
第一行之后的行为空。需要什么额外的代码才能完成这项工作? (从设计的角度来看,不需要额外的代码,但显然 WPF 设计得不好)【参考方案7】:如果您使用 MVVM 模式,您可以将您的 VM 的 SelectedRecord
属性与 DataGrid 的 SelectedItem
绑定,这样您的 VM 中始终拥有 SelectedValue
。
否则,您应该使用 DataGrid 的 SelectedIndex
属性。
【讨论】:
我不使用 MVVM,我只是从 WPF/C#/.NET 开始。如果我写«ContentDataGrid.SelectedIndex»,我会在 DataGrid 中获得所选行的索引,我不需要索引,而是实际值,例如 «646 Jim Biology»。那么我怎样才能得到它呢? 您应该考虑使用绑定对象,以便可以绑定数据网格的 SelectedItem 属性。在您的情况下,您应该尝试导航到 Datagrid 属性以了解它是否存储了选定的项目属性。 +1。第一句话正是我要找的! SelectedRecord 属性?我假设我必须自己设置它。任何建议或代码示例都会很棒 @ema ,如果能提供代码示例就好了。【参考方案8】:使用您的模型类来获取从数据网格中选择的行值,例如,
XDocument xmlDoc = XDocument.Load(filepath);
if (tablet_DG.SelectedValue == null)
MessageBox.Show("select any record from list..!", "select atleast one record", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
else
try
string tabletID = "";
/*here i have used my model class named as TabletMode*/
var row_list = (TabletModel)tablet_DG.SelectedItem;
tabletID= row_list.TabletID;
var items = from item in xmlDoc.Descendants("Tablet")
where item.Element("TabletID").Value == tabletID
select item;
foreach (var item in items)
item.SetElementValue("Instance",row_list.Instance);
item.SetElementValue("Database",row_list.Database);
xmlDoc.Save(filepath);
MessageBox.Show("Details Updated..!"
+ Environment.NewLine + "TabletId: " +row_list.TabletID + Environment.NewLine
+ "Instance:" + row_list.Instance + Environment.NewLine + "Database:" + row_list.Database, "", MessageBoxButton.YesNoCancel, MessageBoxImage.Information);
catch (Exception ex)
MessageBox.Show(ex.StackTrace);
【讨论】:
【参考方案9】:在我尝试了 Fara 的答案后才发现这个,但它对我的项目不起作用。只需将列从“数据源”窗口拖放到标签或文本框。
【讨论】:
【参考方案10】:这在这个 DataGrid dg 中非常简单,项目类填充在 datagrid 中,listblock1 是一个基本框架。
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
try
var row_list = (Item)dg.SelectedItem;
listblock1.Content = "You Selected: " + row_list.FirstName + " " + row_list.LastName;
catch
public class Item
public string FirstName get; set;
public string LastName get; set;
【讨论】:
【参考方案11】:private void Fetching_Record_Grid_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
IInputElement element = e.MouseDevice.DirectlyOver;
if (element != null && element is FrameworkElement)
if (((FrameworkElement)element).Parent is DataGridCell)
var grid = sender as DataGrid;
if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
//var rowView = grid.SelectedItem as DataRowView;
try
Station station = (Station)grid.SelectedItem;
id_txt.Text = station.StationID.Trim() ;
description_txt.Text = station.Description.Trim();
catch
【讨论】:
【参考方案12】:如果我选择第二行 -
Dim jason As DataRowView
jason = dg1.SelectedItem
noteText.Text = jason.Item(0).ToString()
noteText 将是 646。这是 VB,但你懂的。
【讨论】:
【参考方案13】:好吧,我会提出适合我的类似解决方案。
private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
try
if (DataGrid1.SelectedItem != null)
if (DataGrid1.SelectedItem is YouCustomClass)
var row = (YouCustomClass)DataGrid1.SelectedItem;
if (row != null)
// Do something...
// ButtonSaveData.IsEnabled = true;
// LabelName.Content = row.Name;
catch (Exception)
【讨论】:
【参考方案14】:public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row) yield return row;
private void DataGrid_Details_SelectionChanged(object sender, SelectionChangedEventArgs e)
try
var row_list = GetDataGridRows(DataGrid_Details);
foreach (DataGridRow single_row in row_lis)
if (single_row.IsSelected == true)
MessageBox.Show("the row no."+single_row .GetIndex ().ToString ()+ " is selected!");
catch
【讨论】:
以上是关于在 DataGrid WPF 中获取选定的行项的主要内容,如果未能解决你的问题,请参考以下文章