In a wpf datagrid if the datagrid is wider than the sum of the column widths, you get trailing space. By default, clicking in this area does not select the row nor does the selection row highlighting cover this area.
How can you register clicks from this area into selecting the appropriate row and also allow the selection row highlighting to extend into this area.
This question:
WPF DataGrid full row selection
is similar but I cannot add a dummy column nor set my column widths to *.
<DataGrid Name="dg">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<EventSetter Event="MouseLeftButtonDown" Handler="DataGridRow_MouseLeftButtonDown" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource {x:Static SystemColors.HighlightBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
with this code behind
private void DataGridRow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
dg.SelectedIndex = (sender as DataGridRow).GetIndex();
}
should work.
Related
I'm trying to change row style while adding items to DataGrid.
<DataGrid x:Name="datagrid1" HorizontalAlignment="Stretch" Height="auto" Margin="10,64,0,0"
VerticalAlignment="Stretch" Width="auto" AutoGenerateColumns="False" DataContext="{Binding}" ItemsSource="{Binding}">
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding UIvisibility}" Value="-2">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding UIvisibility}" Value="-1">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
<DataTrigger Binding="{Binding UIvisibility}" Value="-0">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.ItemContainerStyle>
</DataGrid>
kMS(i).line(7) has "-2","-1","-0" or "1" for each kMS(i) as String, And will be assigned to Item.Visibility
For Instance
kMS(1).line(7)="-1"
kMS(4).line(7)="-0"
kMS(369).line(7)="1"
kMS(897).line(7)="-2"
Codes are following
Dim c3 As DataGridTextColumn = New DataGridTextColumn
c3.Binding = New System.Windows.Data.Binding("UIvisibility")
c3.Visibility = 1
datagrid1.Columns.Add(c3)
Dim Additem(kMS.Length - 1) As Item
For i = 0 To kMS.Length - 1
Additem(i) = New Item
Additem(i).Callback = kMS(i).line(8)
Additem(i).Keyboard = "No Assign"
If kMS(i).line(3).Remove(0, 2) <> "FFFFFFFF" Then
Additem(i).Keyboard = kMS(i).line(3).Remove(0, 2)
End If
Additem(i).UIvisibility = kMS(i).line(7)
datagrid1.Items.Add(Additem(i))
Next
Public Class Item
Public Property Callback As String
Public Property Keyboard As String
Public Property UIvisibility As String
End Class
It's not working well and the result would be only rows with transparent background and black foreground.
Actutal image of the application
What am I missing?
It would help if you post a screenshot of your problem.
My guess is that you change the property of the wrong WPF control. For changing the background, DataGridRow is ok only for the part of the row which is not covered by any row. This can happen when the DataGrid is wider than all columns together.
For the columns, DataGridCell, i.e. TextBox gets painted over the DataGridRow. So if the DataGridRow is transparent, but the TextBox is white, you will see a white background.
This kind of problem WPF often avoids using graphical inheritance, meaning when a property is set in a container, all controls who don't write their own value for that property will inherit the value from the container.
Unfortunately, DataGrid behaves quite differently. Usually, your problems go away if you don't depend on graphical inheritance but style the correct control.
2 Recommendations
1) Don't use triggers to change the style. You can easily do it using bindings:
<datagrid.rowstyle>
<style targettype="DataGridRow">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},
Path=Item.Quantity, Converter={StaticResource QuantityToBackgroundConverter}}"/>
</style>
</datagrid.rowstyle>
The Foreground could be done like this:
<Setter Property="Foreground"
Value="{Binding
RelativeSource={RelativeSource Self},
Path=Text,
Converter={StaticResource QuantityToForegroundConverter}}" />
2) Formatting the DataGrid is a major headache. I spent weeks trying to understand it. Read my article where I provide a lot of background information and many samples how important formattings can be done:
www.codeproject.com: Guide to WPF DataGrid formatting using bindings
i have a DataGrid, i want to add each row of this DataGrid, one by one, then check the information in that Row, if something in it (lets call it cancel) is true, that row is colored black, otherwise its colored white.
i'd also want to know how the contents in that row can be modified, like set text of each cell in it, and then add it to the DataGrid.
To fill and modify a DataGrid you bind an ObservableCollection to the DataGrid's ItemSource Property.
You can then modify the Collection as you like. For the layout you can use a Style.
<DataGrid ItemsSource="{Binding Collection}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Cancel}" Value="false">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<!--
...
-->
</DataGrid>
How can I change the new row style (of CanUserAddRows) I want the user to notice to the new row.
thanks
I've not tested this, but I think it should work. You can try adding some Style for the DataGridRow. Add some Trigger listening to IsNewItem. Then you can change almost everything related to the matched DataGridRow via the Trigger Setter. The following code will try highlighting the new row by setting a red border around it:
<DataGrid ItemsSource="someSource">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsNewItem" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<!-- remaining code ... -->
</DataGrid>
I have a style on my datagrid to disable a DataGridRow based on a property binding. This makes the row unselectable, which is what I want. However, I am still able to select the disabled rows using at least 2 other ways. The first is if I use a dragging motion between two enabled rows that surround the disabled row. The second is if I click on the "select all" button on the top left of the datagrid. Is there a way to make specific rows completely unselectable?
This is what I currently have:
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding DisableMe}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
What about using the SelectionChanged event to undo the selection? I really don't think there is a straightforward way to it, anyway.
You could also change the row style so it appears unselected even if it IS selected, and filter it out the selection through code...
I just stumbled upon this thread with the same problem, and I want to point out that you can simply set enabled to false.
I don't think of any proper solution to this question. But as a workaround you can bind 'IsHitTestVisible' property of DataGrid to 'IsEnabled'.
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="IsHitTestVisible" Value="{Binding RelativeSource={RelativeSource Self},Path=IsEnabled}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DisableMe}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
Is there a way, using XAML, to dynamically set the background of a row based on the content of one of it's cells?
Thanks,
Phil
You can define a style for a row and change the color using DataTrigger. Something like this:
<DataGrid>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding BooleanPropertyOnObjectBoundToRow}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
Here BooleanPropertyOnObjectBoundToRow is a boolean property on your data object one the cells is bound to.