Reputation: 4444
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;
}
Upvotes: 0
Views: 2197
Reputation: 7325
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;
}
Upvotes: 2
Reputation: 269
hi you can set a flag on the binding at the checkboxcolumn.
There is a NotifyOnTargetUpdated
with fires an TargetUpdated
event when the target (your checkbox) changes.
With NotifyOnTargetUpdated=True
on your binding you activate them.
Your DataGridCheckBoxColumn
looks then like this:
<DataGridCheckBoxColumn x:Name="colSelektiraj" Binding="{Binding IsChecked, NotifyOnTargetUpdated=True}" Header="" Width="10*" />
On the Datagrid use the TargetUpdated="DataGrid_TargetUpdated"
event to get notified. Your datagrid looks then like this:
<DataGrid Name="dtgTest" IsReadOnly="True" TargetUpdated="DataGrid_TargetUpdated" ...>
To get notified when the selection changed use the SelectionChanged
event as you did it already.
Upvotes: 0
Reputation: 1937
If you have a ViewModel (MVVM) which represents the Data for each row. You should/could have a bool property there which represents the CheckBox state (rather than doing so from code behind).
Next, you can Bind DataGrid's SelectedItem to an Object (of relevant type) and test whether that gets fired even when you click same item multiple times. If it does (at least in DevExpress gridControls) - You should Flip the bool property in the Setter for the SelectedItem.
Upvotes: 0