Good day. I'm still a junior programmer and recently started coding in WPF. I have a datagrid where I generate my own columns. In one specific column, a DataGridTextColumn, I have to apply a spell check (the user can add comments to this field). But I can't manage to do this. I have tried applying a style but no luck. Any assistance would be appreciated! Here is the coding for the column:
<DataGridTextColumn x:Name="clValueComment" Binding="{Binding CommentColumn, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="ROOTCAUSE OR COMMENT" Width="*" IsReadOnly="False" Style="{StaticResource Spell}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
<DataTrigger Binding="{Binding valueTypeID}" Value="1">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label IsEnabled="False"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
After playing around with some more of the Styling options, I found a solution that seems to be working. I'll post it as an answer for someone who might come across the same requirement. The XAML coding that did the trick is:
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="SpellCheck.IsEnabled" Value="True"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
Related
I'm working in a WPF C# project, I had a lot of problems showing tooltips for validation purposes and I came across this solution in another post here on StackOverflow.
<DataGridTextColumn MinWidth="80" ...>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
and though this works and applies the tooltip style to the columns, I have to paste it in all the columns
I want it to happen... I tried to create a style already but I was unsuccessful. I think it as something to do with the bindings and the "relative source" thing.
Is it possible to create a style out of this and apply it to every column, how do I do it?!
I just figured out how to make it work!
<DataGrid.Resources>
<Style x:Key="DataGridTextColumnError" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
The value binding needed to be changed to static.
Hope this helps someone!
<Style x:Key="myStyle" TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="ColumnIndex" Value="2">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
I remembered I Was able to accomplish this with code similar to this but can't remember how I did it anymore.
If I understand what you are trying to do, you want the text color of the cells in column 2 to be red.
Here is your style...
<Style x:Key="myStyle" TargetType="DataGridCell">
<Setter Property="Foreground" Value="Red"/>
</Style>
Then for the column that you want to style...
<DataGridTextColumn Header="Value" CellStyle="{StaticResource myStyle}"/>
You are targeting "ColumnIndex" which does not exist in DataGridCell class.
Creating column definitions makes adding a style to the second column only much easier to do rather than relying on a trigger.
<DataGrid AutoGenerateColumns="False">
<DataGrid.Resources>
<Style x:Key="myStyle" TargetType="DataGridCell">
<Setter Property="Background" Value="Beige" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn />
<DataGridTextColumn CellStyle="{StaticResource myStyle}" />
<DataGridTextColumn />
</DataGrid.Columns>
</DataGrid>
I don't really know how to describe it. Best thing is to show it:
Do you see those thin black lines?
Here is Xaml snippet:
<DataGrid Grid.Row="4" Grid.Column="1" ItemsSource="{Binding RunnedTests}" Margin="5"
HeadersVisibility="None" AutoGenerateColumns="False" IsEnabled="False"
GridLinesVisibility="None" RowBackground="#FF268AEC" BorderBrush="#FF268AEC" BorderThickness="0">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Width="4*" />
<DataGridTextColumn Binding="{Binding PassedOrFailed}" Width="*">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsPassed}" Value="True">
<Setter Property="Foreground" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
The BorderBrush & BorderThickness doesn't really do anything for it. Without those properties it will stay the same.
Here is a Picture of the same DataGrid without the RowBackground property:
More notes:
Background property of DataGrid does nothing
I don't know if you can see from my code, but hides there a frustrating struggle with DataTrigger. I wanted to display the words "passed" or "failed" depending on the IsPassed bool property via DataTrigger, but could not make it. At the end I had to compromise and create the property PassedOrFailed in the model. It is quite stupid in my point of view, can you suggest a way to accomplish it?
Thanks!
Update:
I forgot to mention two additional styles:
<Style TargetType="DataGridCell">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Transparent" />
</Style>
I'm trying to change inactive data with strikethrough decoration.
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="IsTabStop" Value="True" />
<Setter Property="TextDecorations" Value="{Binding SelectedEntryType.TypeOfEntry, Converter={StaticResource DisplayValueToStrikethrough}}"/>
</Style>
</DataGrid.CellStyle>
The problem is the following: The member "TextDecorations" is not recognized or is not accessible.
I'm using MVVM design pattern.
I already added the System.Windows dll. How can I fix this error? Thank you.
Try write TextBlock.TextDecorations like this:
<Setter Property="TextBlock.TextDecorations"
Value="{Binding SelectedEntryType.TypeOfEntry, Converter={StaticResource DisplayValueToStrikethrough}}" />
Edit
In this case, you need to implement DataGridTemplateColumn with TextBlock or use ElementStyle for DataGridTextColumn:
<DataGridTextColumn Header="Test">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations" Value="Strikethrough" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
I have a DataGrid, and in that grid, some of the columns are marked Read only:
<DataGrid AutoGenerateColumns="False">
<DataGrid.Columns>
<!-- this column is read only -->
<DataGridTextColumn Header="Column A" Binding="{Binding Path=PropertyA}" IsReadOnly="True" />
<!-- this column is EDITABLE -->
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<!-- this column is read only -->
<DataGridTextColumn Header="Column C" Binding="{Binding Path=PropertyC}" IsReadOnly="True" />
</DataGrid.Columns>
I want that "Name" column to be visually distinguishable by the header that it is editable, when the other two columns are not. I can't seeem to get to the IsReadOnly property of the DataGridColumn, though.
I'm effectively trying to do something like:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader" >
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumn}, Path=IsReadOnly}" Value="false">
<Setter Property="Background" Value="Azure" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.ColumnHeaderStyle>
From this question:
Binding Visible property of a DataGridColumn in WPF DataGrid, it appears that DataGridColumn isn't a framework element, so i can't find it using RelativeSource AncestorType=DataGridColumn. That poster says they used a static resource to find it, but doesn't explain what/how (and several answers there are questions of how the poster solved it)
This question: How to get DataGridColumnHeader from DataGridColumn?, looks like i could get to it from code, but i'd really like this to just be xaml and generic to apply to any data grid.
Is there something simple i'm overlooking?
Answering my own question, in case anyone else runs into this...
It turns out there isn't a lot you can do here from XAML, because of some of the things mentioned in the question. The simplest thing i could do from XAML was make the headers of the editable columns bold to differentiate them from the rest of the columns.
<DataGridTextColumn Header="Editable Column" Binding="{Binding Path=EditableProperty,Mode=TwoWay}" IsReadOnly="False" Width="150">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="ToolTip" Value="You can modify the values of this column."/>
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
You can do more complicated things, like:
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Trigger.Setters>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" />
<GradientStop Color="LightSteelBlue" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
But you end up getting some really wierd behaviors, where the sort icon disappears, or other wierd things. If you want to change the column headers and make it look consistant, you pretty much have to restyle the whole datagrid and all of its headers through styles and templates.
DataGridColumnHeader has property Column, which has the property IsReadOnly
<Label Content="(read only)" DockPanel.Dock="Bottom">
<Label.Style>
<Style TargetType="Label">
<Setter Property="Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader},Path=Column.IsReadOnly}" Value="True">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
In your example you could do:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader" >
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=Column.IsReadOnly}" Value="False">
<Setter Property="Background" Value="Azure" />
</DataTrigger>
</Style.Triggers>
</Style>