I want to implement GridView functionally in WPF. I have done that in may websites and decided to write an article about it.
For implementing GridView functionally in WPF, there are two approaches; they are:
- GridView using ListView.
- DataGrid.
In this article, I am using a DataGrid with the WPFToolkit.dll.
First you need to download the WPFToolkit.dll.
You can download these DLLs from the following site:
http://wpf.codeplex.com/releases/view/40535
Create a new WPF project and add the WPFToolkit.dll reference to it.
Find the control and its value on button click event.
I have a DataGrid containing a button and a label control. Now I want to find this label and its values on the button click event (i.e. btnUserId_Click).
You can use the following code to find the label control and its values.
XAML Code
<my:DataGrid Name="GridView1" ItemsSource="{Binding}" AutoGenerateColumns="False" >
<my:DataGrid.Columns>
<my:DataGridTemplateColumn Header="Vehicle Reg. No." Width="SizeToCells">
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnUserId" Cursor="Hand" Tag="{Binding Path=source_address }" Click="btnUserId_Click" Content="{Binding Path=VehicleReg }" Style="{StaticResource LinkButton}"></Button>
</DataTemplate>
</my:DataGridTemplateColumn.CellTemplate>
</my:DataGridTemplateColumn>
<my:DataGridTemplateColumn Header="source_address" Width="SizeToCells" Visibility="Hidden">
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label x:Name="lblsource_address" Content="{Binding Path=source_address}" />
</DataTemplate>
</my:DataGridTemplateColumn.CellTemplate>
</my:DataGridTemplateColumn>
</my:DataGrid.Columns>
</my:DataGrid>
private void btnUserId_Click(object sender, RoutedEventArgs e)
{
//Find the DataRowView for DataGrid.
DataRowView Grdrow = ((FrameworkElement)sender).DataContext as DataRowView;
//Fidn the DataGrid row index
int rowIndex = GridView1.Items.IndexOf(Grdrow);
//Find the DataGridCell
DataGridCell cell = GetCell(rowIndex, 1); //Pass the row and column
//Find the "lblVehicleName" lable.
Label lblsource_address = GetVisualChild<Label>(cell); // pass the DataGridCell as a parameter to GetVisualChild
string _value = lblsource_address.Content;
}
public DataGridCell GetCell(int row, int column)
{
DataGridRow rowContainer = GetRow(row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
if (presenter == null)
{
GridView1.ScrollIntoView(rowContainer, GridView1.Columns[column]);
presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
}
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
return cell;
}
return null;
}
public DataGridRow GetRow(int index)
{
DataGridRow row = (DataGridRow)GridView1.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
GridView1.UpdateLayout();
GridView1.ScrollIntoView(GridView1.Items[index]);
row = (DataGridRow)GridView1.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
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;
}
Description
-
First you need to find the "DataRowView" from the button click event:
DataRowView Grdrow = ((FrameworkElement)sender).DataContextas DataRowView;
-
Then you need to find the row index of the "DataGrid" row index:
int rowIndex = GridView1.Items.IndexOf(Grdrow);
-
You need to use the GetCell() method to get the required cell. The GetCell() method will take two arguments. One is the row and another is the column. I have passed the row index as the row and 1 as my column because my "lblsource_address" label is present in the first column.
DataGridCell cell = GetCell(rowIndex, 1);
-
GetVisualChild() will help to find the control and its values.
Label lblsource_address = GetVisualChild<Label>(cell);
string _value = lblsource_address.Content;