I'm working on a small WPF application, when I click on a row I'm making my checkbox column selected/unselected. This is how my rows look:
And here is my code:
private void dtgTest_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (dtgTest.SelectedItem != null)
{
CheckBox checkbocColumn = (dtgTest.Columns[3].GetCellContent(dtgTest.SelectedItem) as CheckBox);
checkbocColumn.IsChecked = !checkbocColumn.IsChecked;
var selectedItem = (BillItemInSerie)dtgTest.SelectedItem;
var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
obj.IsChecked= (bool)checkbocColumn.IsChecked;
}
}
Here is how I'm filling DataGrid:
public Test_Window()
: this()
{
databaseValues = Controller.Instance.GetById(Id);
dtgTest.ItemsSource = null;
dtgTest.ItemsSource = databaseValues;
}
So when form is generated I acctually get all items from DB
And here is my XAML:
<DataGrid Name="dtgTest" IsReadOnly="True" VirtualizingStackPanel.VirtualizationMode="Standard" EnableColumnVirtualization = "True" EnableRowVirtualization ="True" MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0" HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2" SelectionChanged="dtgTest_SelectionChanged">
<DataGrid.CellStyle>
<StaticResource ResourceKey="DataGridCentering"/>
</DataGrid.CellStyle>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="LightBlue"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Value1}" Header="" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*" />
<DataGridTextColumn Binding="{Binding Value2}" Header="" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*" />
<DataGridTextColumn x:Name="colFormatedDate" Binding="{Binding ExpireDate, StringFormat ={}{0:MM/yyyy}}" Header="" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="20*" />
<DataGridCheckBoxColumn x:Name="colSelektiraj" Binding="{Binding IsChecked}" Header="" Width="10*" />
</DataGrid.Columns>
</DataGrid>
But issue is here when I click on a row and make checkbox column selected (LIKE IN EXAMPLE IMAGE ABOVE) , and If I immediately change my mind and click again on selected row to change the state of checkbox column I won't be able to do it, because dtgTest_SelectionChanged
won't trigger because I did not change selection..
So I guess detecting if a row is clicked might help me here? So I might execute similar code as it is in dtgTest_SelectionChanged
event?
Any kind of help would be awesome! Thanks, guys
Cheers
EDIT AFTER Rekshino help:
<DataGrid Name="dtgTest" IsReadOnly="True" VirtualizingStackPanel.VirtualizationMode="Standard" EnableColumnVirtualization = "True" EnableRowVirtualization ="True" MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0" HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2" SelectionChanged="dtgTest_SelectionChanged" PreviewMouseDown="dtgTest_PreviewMouseDown">
<DataGrid.CellStyle>
<StaticResource ResourceKey="DataGridCentering"/>
</DataGrid.CellStyle>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
<Style TargetType="DataGridCell">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="dtgTest_PreviewMouseDown"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Value1}" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*" />
<DataGridTextColumn Binding="{Binding Value2}" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*" />
<DataGridTextColumn x:Name="colFormatedDate" Binding="{Binding ExpireDate, StringFormat ={}{0:MM/yyyy}}" Foreground="Black" FontSize="15" FontFamily="Verdana" Width="20*" />
<DataGridCheckBoxColumn x:Name="colSelektiraj" Binding="{Binding IsChecked, NotifyOnTargetUpdated=True}" Header="" Width="10*" />
</DataGrid.Columns>
</DataGrid>
C# :
private void dtgTest_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var cell = sender as DataGridCell;
if (cell == null)
{
return;
}
DataGridRow parGridRow = null;
var visParent = VisualTreeHelper.GetParent(cell);
while (parGridRow == null && visParent != null)
{
parGridRow = visParent as DataGridRow;
visParent = VisualTreeHelper.GetParent(visParent);
}
if (parGridRow == null) { return; }
var selectedItem = (parGridRow.DataContext as BillItemInSerie);
var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
obj.IsChecked = (bool)!obj.IsChecked;
}
You can set mouse event handler for the cell, get the row and make what you want with it. I have removed event handler for SelectionChanged
, because you don't need it in this solution.
<DataGrid Name="dtgTest" IsReadOnly="True" VirtualizingStackPanel.VirtualizationMode="Standard" EnableColumnVirtualization = "True" EnableRowVirtualization ="True" MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0" HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2">
<DataGrid.Resources>
<Style TargetType="DataGridCell">
<!-- If you have to apply another style, then use BasedOn-->
<!--<Style TargetType="DataGridCell" BasedOn="{StaticResource DataGridCentering}">-->
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="PreviewMouseDown"/>
</Style>
</DataGrid.Resources>
...
</DataGrid>
private void PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var cell = sender as DataGridCell; if (cell == null) { return; }
DataGridRow parGridRow = null;
var visParent = VisualTreeHelper.GetParent(cell);
while (parGridRow == null && visParent != null)
{
parGridRow = visParent as DataGridRow;
visParent = VisualTreeHelper.GetParent(visParent);
}
if (parGridRow == null) { return; }
var selectedItem = (parGridRow.DataContext as BillItemInSerie);
var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
obj.IsChecked= (bool)!obj.IsChecked;
//e.Handled = true;
}