With this blog we will discuss a user scenario wherein the row in the C1DataGrid gets selected when the TextBox contained inside the C1DataGridTemplateColumns is selected. The behavior would be handled in the case of SingleRow as well as MultipleRow Selection modes following the MVVM approach.

C1DataGrid

This can be implemented easily in case of a "Non-MVVM pattern" using TextBox.GotFocus() Event but in case of MVVM we will handle the behavior in ViewModel through EventTriggers.

The following steps will guide you on how to implement in such a scenario :

Adding External Assemblies


Step 1: First of all, we need to add two external assemblies (System.Windows.Interactivity and Microsoft.Expression.Interactions) in our project, which provides extended functionality to handle events of UIElements using Triggers. These dlls could be found on the following link location:

C:\Program Files\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries

Step 2: Now, add the references to these dlls in your XAML as :


xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:si="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"



Binding the GotFocus event of the contained Textboxes


Step 3: Now, add  C1DataGrid into your project and create some C1DataGridTemplateColumns containing TextBoxes. Next, we will bind the GotFocus() Event of these Textboxes as follows :


<c1:C1DataGrid Name="c1DataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding EmployeeList}">
<c1:C1DataGrid.Columns>
<c1:DataGridTemplateColumn Header="FirstName">
<c1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="txt1" Text="{Binding FirstName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=c1:C1DataGrid},
Path=DataContext.RowClickCommand}" CommandParameter="{Binding ElementName=txt1}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</DataTemplate>
</c1:DataGridTemplateColumn.CellTemplate>
<c1:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding FirstName}"/>
</DataTemplate>
</c1:DataGridTemplateColumn.CellEditingTemplate>
</c1:DataGridTemplateColumn>
</c1:C1DataGrid.Columns>
</c1:C1DataGrid>


Handling CallBack method for the GotFocus Event


Step 4: Next, we will create a CallBack method for the TextBox.GotFocus Event. For this, we need to implement INotifyPropertyChanged interface to raise an event whenever the TextBox’s Background property is changed. And in the CallBack method we retrieve the index of the currently selected TextBox, in order to make its parent row as selected.


public void TextBoxClick(object parameter)
{
int index = ((C1.WPF.DataGrid.DataGridCellPresenter)(((System.Windows.Controls.Primitives.TextBoxBase)(parameter)).Parent)).Row.Index;
if (!flag)
{
for (int i = 0; i < c1DataGrid1.Rows.Count - 1; i++)
{
for (int j = 0; j < c1DataGrid1.Columns.Count; j++)
{
(c1DataGrid1[i, j].Presenter.Content as TextBox).Background = new SolidColorBrush(Colors.White);
}
}
}
for (int j = 0; j < c1DataGrid1.Columns.Count; j++)
{
(c1DataGrid1[index, j].Presenter.Content as TextBox).Background = new SolidColorBrush(Colors.LightBlue);
c1DataGrid1.CurrentRow = c1DataGrid1.Rows[index];
}
}


Step 5: Finally, we like to handle multiple row selection in C1DataGrid. For this, we need to handle PreviewKeyDown and PreviewKeyUp Events using a flag which determines whether to select multiple rows or not.


void c1DataGrid1_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
flag = false;
}

void c1DataGrid1_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
flag = true;
}


Download Sample