从 datarowview WPF 获取 datagridrow
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13470667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting datagridrow from a datarowview WPF
提问by user589195
I am trying to loop through each row in a datagrid, pull out a column value, pass this value to a method and style that row based on the result of the method.
我试图遍历数据网格中的每一行,拉出一个列值,将此值传递给一个方法并根据该方法的结果设置该行的样式。
After finding out I cant just loop through the rows of a datagrid I found thispost detailing how it was possible.
在发现我不能循环遍历数据网格的行后,我发现这篇文章详细说明了它是如何实现的。
I have modified slightly so that I am working with datarowview objects.
我稍作修改,以便使用 datarowview 对象。
The issue I now have is that
我现在的问题是
var dgRow = grid.ItemContainerGenerator.ContainerFromItem(r) as DataGridRow;
is always returning null.
总是返回空值。
Please could someone advise as to why this is happening in my case and if they can see an easier way of doing it.
请有人建议为什么在我的情况下会发生这种情况,以及他们是否可以看到更简单的方法。
Please let me know if you need anymore info.
如果您需要更多信息,请告诉我。
Heres my code:
这是我的代码:
private void colorArchived( DataGrid grid , GX3MaterialSelectionData data)
{
var row = GetDataGridRows(grid);
foreach (DataRowView r in row)
{
var dgRow = grid.ItemContainerGenerator.ContainerFromItem(r) as DataGridRow;
int val = int.Parse(r.Row[0].ToString());
if ( data.IsArchived(val) )
{
// style will be defined in xaml
dgRow.Style = mystyle;
}
}
}
public IEnumerable<DataRowView> GetDataGridRows(DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = item;
if (null != row) yield return (DataRowView)row;
}
}
回答by D_Learning
As per your Question, i have just updated the StyleSelector Class described above:
根据您的问题,我刚刚更新了上述 StyleSelector 类:
public class RowStyle : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
var dgRow = item as DataGridRow;
int val = int.Parse(dgRow.Row[0].ToString());
if ( data.IsArchived(val) )
{
return Mystyle;
}
return base.SelectStyle(item, container);
}
// style will be defined in xaml
public Style Mystyle
{
get;
set;
}
}
NOTE: Describe "GX3MaterialSelectionData data" as Static for the Class, so that the above class could access it directly.
注意:将“GX3MaterialSelectionData 数据”描述为类的静态,以便上述类可以直接访问它。
回答by Prashant Manjule
METHOD 1:
方法一:
//simple way using SelectionChanged or RowEditEnding event without DataRowView
DataRowView row = (DataRowView)t_DataGrid.SelectedItems[0];
DataGridRow row1 = e.Row;
METHOD 2:
方法二:
//convert datagridrow to datarowview (it works sometimes only databinding problems)
DataGridRow dgr = FindVisualParent<DataGridRow>(txtPcode);
DataRowView drv = dgr.DataContext as DataRowView;
METHOD 3:
方法三:
//it needs improvements
DataRowView dataRow = (DataRowView)t_DataGrid.SelectedItem;
//subitem
int i_cell = t_DataGrid.CurrentCell.Column.DisplayIndex;
int i= int.Parse(dataRow.Row.ItemArray[id_cell].ToString());
//get datagrid by index
DataGridRow dgr = DG.GetRow(t_DataGrid_temp, i);
//create this special Datagrid class for getting full access over datagrid
public static class DG
{
/* Get the Cell using Row Index and Column Index */
public static DataGridCell GetCell(DataGrid grid, int row, int column)
{
DataGridRow rowContainer = GetRow(grid, row);
return GetCell(grid, rowContainer, column);
}
/* Get the DataGridRow using Row Index */
public static DataGridRow GetRow(DataGrid grid, int index)
{
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// May be virtualized, bring into view and try again.
grid.UpdateLayout();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
/* Get the Cell using DataGridRow Object and Column Index */
public static DataGridCell GetCell(DataGrid grid, DataGridRow row, int column)
{
if (row != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
if (presenter == null)
{
grid.ScrollIntoView(row, grid.Columns[column]);
presenter = GetVisualChild<DataGridCellsPresenter>(row);
}
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
return cell;
}
return null;
}
/* Get the Child Element Based on Type */
public static T GetVisualChild<T>(Visual parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
/* Get the Child by name */
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null) return null;
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null) break;
}
else if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
/*get parent*/
public static T GetParent<T>(DependencyObject d) where T : class
{
while (d != null && !(d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
//new
public static Visual GetChildrenByType(Visual visualElement, Type typeElement, string nameElement)
{
if (visualElement == null) return null;
if (visualElement.GetType() == typeElement)
{
FrameworkElement fe = visualElement as FrameworkElement;
if (fe != null)
{
if (fe.Name == nameElement)
{
return fe;
}
}
}
Visual foundElement = null;
if (visualElement is FrameworkElement)
(visualElement as FrameworkElement).ApplyTemplate();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visualElement); i++)
{
Visual visual = VisualTreeHelper.GetChild(visualElement, i) as Visual;
foundElement = GetChildrenByType(visual, typeElement, nameElement);
if (foundElement != null)
break;
}
return foundElement;
}
}
回答by Andy
You could use a StyleSelector in this case.
在这种情况下,您可以使用 StyleSelector。
public class RowStyle : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
// here the item property is the entity that the grid row is bound to.
// check whatever values you want on it and locate a matching style with
// find resource.
// return a reference to the correct style here
// or allow this to run if you want the default style.
return base.SelectStyle(item, container);
}
}
to use it on your data grid you need to set the RowStyleSelector property.
要在数据网格上使用它,您需要设置 RowStyleSelector 属性。
<Window x:Class="Rich.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Rich"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:RowStyle x:Key="styleSelector"/>
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding Items}" RowStyleSelector="{StaticResource styleSelector}">
<DataGrid.Columns>
<DataGridTextColumn Header="test" Binding="{Binding Test1}"/>
<DataGridTextColumn Header="test2" Binding="{Binding Test2}"/>
<DataGridTextColumn Header="test3" Binding="{Binding Test3}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

