How can I localize the value of boolean groupheaders in RadGridView - wpf

I have a telerik WPF RadGridView in which I have localized most text strings, but when grouping on a boolean field, it shows true/false, I want to localize these values as well, but I can't figure out how. See image below for an illustration.
To localize the other strings, I am using a resx file with the keys found at http://www.telerik.com/help/wpf/gridview-localization2.html.
edit: I have also set the Language property of the user control to the appropriate locale

I managed to solve this with a rather nasty workaround, so I'm still looking for a better solution, but if anyone needs this for the future, I solved it like this:
<telerik:GridViewCheckBoxColumn Header="{Binding Resx.Confirmed}" DataMemberBinding="{Binding Confirmed}">
<telerik:GridViewCheckBoxColumn.GroupHeaderTemplate>
<DataTemplate>
<Label>
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Content" Value="{Binding DataContext.Resx.True, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Group.Items[0].Confirmed}" Value="False">
<Setter Property="Content" Value="{Binding DataContext.Resx.False, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</DataTemplate>
</telerik:GridViewCheckBoxColumn.GroupHeaderTemplate>
</telerik:GridViewCheckBoxColumn>

Related

Get ValidationError in specific xaml element using a template

i have the following code snippet:
<ContentControl Height="16">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=txtDistanceH, Path=(Validation.HasError)}" Value="True">
<Setter Property="Content" Value="{Binding ElementName=txtDistanceH, Path=(Validation.Errors)[0]}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
Now i want to put the style in a separate file instead of inline. However i would like to be able to specify which element it should get the Validation.Errors from, so i can use a single template for several different controls.
Is there any way to tell the template where it should get the Validation.Errors from, OTHER than binding to an element by name?
I tried setting the ContentControls DataContext to the element txtDistanceH, but then i just get a binding error saying that the property cannot be found on the root-element.
thanks for taking the time to answer my question. I've tried it and it works!
However i do have a comment and another related question.
The code i have now is:
<!-- Set content of contentcontrol to the ValidationError of a control stored in Tag, if there is one -->
<Style x:Key="ShowValidationError" TargetType="ContentControl">
<Style.Resources>
<x:Static x:Key="EmptyString" Member="System:String.Empty" />
</Style.Resources>
<Setter Property="Content" Value="{StaticResource EmptyString}" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.(Validation.HasError)}" Value="True">
<Setter Property="Content" Value="{Binding RelativeSource={RelativeSource Self}, Path=Tag.(Validation.Errors).CurrentItem}" />
</DataTrigger>
</Style.Triggers>
</Style>
(Validation.Errors).CurrentItem is better than (Validation.Errors)[0], because the latter gives an out of range exception in the debug window when the error is resolved, see This Link for more information. The empty string ensures the control has the same size when its empty as when it has an error.
However even though it compiles and works, i still get some errors during design time. The code responsible is (Validation.HasError) and (Validation.Errors), respectively, in the above snippet.
Property 'Errors' is not attachable to elements of type 'Object'.
The property 'HasError' was not found in type 'Validation'.
Is there any way to fix / suppress these errors?
Bind the Tag property of the ContentControl to the target element using the element name binding and then update the style to use relative source self bindings to the tag to get at the validation errors.
Somewhere in Resources:
<Style x:Key=“ValidationStyle” TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.(Validation.HasError)}" Value="True">
<Setter Property="Content" Value="{Binding RelativeSource={RelativeSource Self}, Path=Tag.(Validation.Errors)[0]}" />
</DataTrigger>
</Style.Triggers>
</Style>
And use it thusly:
<ContentControl Style=“{StaticResource ValidationStyle}” Tag=“{Binding ElementName=txtDistanceH}” />

Dynamically set image of each node

So I have 3 levels of nodes in my TreeView:
A single Root Node (should display Image1.png)
Some second level nodes (should display Image2.png)
Each second level node has some third-level nodes (should display Image3.png)
I'm trying to use a DataTemplate to dynamically assign the display image to each node, depending upon its level. Since level is not as easily available in WPF as it is in WinForms, I simply resorted to using Tag property of TreeViewItems to store their level. Then I wrote this following Style for assigning display images:
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="img" Width="20" Height="20" Stretch="Fill">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Tag}" Value="0">
<Setter Property="Source" Value="Icons\Image1.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Tag}" Value="1">
<Setter Property="Source" Value="Icons\Image2.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock VerticalAlignment="Center" Text="{Binding}" Margin="5,0" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Yes, you guessed it; it doesn't work. Can someone please identify where the problem lies? Or am I doing it just the wrong way?
Right now, your {Binding Tag} will try to find the Tag property of the TreeViewItem's DataContext, not the DependencyProperty. And since, i'm guessing, there is no Tag property in the DataContext, it won't work. If you look at your output Windows in VS, you should see binding errors all over the place.
What you need to do is add the relative source to your binding so it looks at the TreeViewItem instead of the DataContext. Here is an example :
<DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}" Value="0">

Binding to Parent of Unknown Type

I have a style and template for a tooltip and would like to bind some of the content in the tooltip to the parent's error collection. I can get this to work by explicitly setting the AncestorType like in the code below, but I would like this to apply globally. I've tried using UIElement and FrameworkElement with no luck, but I think that's because it's not getting all of the way up the tree to find the correct element.
<ControlTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}, Path=(Validation.HasError)}"
Value="True">
<Setter
Property="Visibility"
TargetName="ErrorBorder"
Value="Visible" />
<Setter
Property="Text"
TargetName="ErrorText"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}, Path=(Validation.Errors)[0].ErrorContent}" />
</DataTrigger>
</ControlTemplate.Triggers>
Simple just try,
AncestorType=Control
You can use AncestorLevel in the RelativeSource.
I was able to get this working by binding to the PlacementTarget of the tooltip using the following binding:
{Binding RelativeSource={RelativeSource Mode=Self}, Path=PlacementTarget.(Validation.HasError)}"
This seems to be working well as long as the PlacementTarget for the tooltip is the control that has the error validation, which in my case it is.

WPF RibbonButton: LargeImageSource and Label not updated via DataTriggers

I'm puzzled by a peculiar phenomenon in RibbonButton's behavior.
Everything works fine when I set the LargeImageSource and the Label statically in XAML:
<ribbon:RibbonButton x:Name="ButtonArchive"
LargeImageSource="..\Assets\archive_insert.png"
Label="{Binding Path=ItemArchiveButton,
Source={StaticResource Strings}}"/>
But when I try to modify these properties via DataTriggers - nothing seems to be happening.
The triggers do work; I can see the other properties - like Command or IsEnabled - set OK in the same trigger. It's just these too...
Here's the XAML:
<ribbon:RibbonButton x:Name="ButtonArchive"
LargeImageSource="..\Assets\archive_insert.png"
Label="{Binding Path=ItemArchiveButton, Source={StaticResource Strings}}">
<ribbon:RibbonButton.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding ="{Binding ElementName=ItemsList, Path=SelectedItem.IsArchived}" Value="false">
<Setter Property="ribbon:RibbonButton.Command" Value="{Binding ArchiveItemCommand}" />
<Setter Property="ribbon:RibbonButton.LargeImageSource" Value="..\Assets\archive_insert.png" />
<Setter Property="ribbon:RibbonButton.Label" Value="{Binding Path=ItemArchiveButton, Source={StaticResource Strings}}" />
</DataTrigger>
<DataTrigger Binding ="{Binding ElementName=ItemsList, Path=SelectedItem.IsArchived}" Value="true">
<Setter Property="ribbon:RibbonButton.Command" Value="{Binding RestoreItemCommand}" />
<Setter Property="ribbon:RibbonButton.LargeImageSource" Value="..\Assets\archive_extract.png" />
<Setter Property="ribbon:RibbonButton.Label" Value="{Binding Path=ItemRestoreButton, Source={StaticResource Strings}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ribbon:RibbonButton.Style>
</ribbon:RibbonButton>
Setting the Command works fine in the both conditions, but not the other 2 properties...
Any advice will be welcome.
I asked the same question at the MSDN forum, and the answer I've got really solved this.
The problem is your setting properties for LargeImageSource and Label in the button itself. When you do this it takes precidence over your style triggers. I suggest using setters in the style to set your defaults, and remove the property settings it the button.

WPF DataGrid Validation error not being caught

I am trying to use exception validation on a cell in a DataGrid together with a style on the DataGridTextColumn's EditingElementStyle to set a tooltip with the content of the error. The error occurs but is not being caught or displayed within WPF.
The code and exception are shown below. Can someone tell me what I need to fix this?
Cheers,
Berryl
Here's the exception:
System.Windows.Data Error: 8 : Cannot save value from target back to source.
BindingExpression:Path=Allocations[6].Amount; DataItem='ActivityViewModel' (HashCode=-938045583);
target element is 'TextBox' (Name='');
target property is 'Text' (type 'String')
TargetInvocationException:'System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. --->
Domain.Core.PreconditionException: An allocation must be less than one day.
Here is the xaml for the DataGridTextColumn:
<dg:DataGridTextColumn
....
EditingElementStyle="{StaticResource cellEditStyle}"
Binding="{Binding Allocations[6].Amount, Converter={StaticResource amtConv},
ValidatesOnExceptions=True}"
/>
And here is the style that should provide Tooltip feedback on he error:
<Style x:Key="cellEditStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<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>
It's probably a bit late, but since I'm running into the same kind of trouble, here is a work-around for further reference (tested with .NET 4.0.30319).
1) Catching the exception
While the following binding code in the original post works fine with a TextBox, for example, it doesn't with a DataGrid text cell (even though the Msn documentation states so):
<!-- Doesn't work -->
<DataGridTextColumn Binding="{Binding Path=Age, ValidatesOnExceptions=True}"
...
/>
You have to add this bit:
<DataGridTextColumn Binding="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=True}"
...
/>
Note that, strangely enough (to me anyway), the exception will be catched and shown with the exclamation mark in the row header. You just won't have the red border nor the possibility to apply a style without the Mode=TwoWay part.
2) Applying a style
Another difficulty is setting a style in case of error, because the editing element will close as soon as you start the validation process. So attaching a style with:
<!-- Doesn't work -->
<DataGridTextColumn Binding="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=True}"
EditingElementStyle="{StaticResource datagridTBStyle}"
...
/>
will simply not work if you want to trigger on a validation error. Likewise with a CellStyle which will not have the error flag to trig on. You have to use a trick and declare a FrameworkElement style, like this:
<DataGridTextColumn Binding="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=True}"
ElementStyle="{StaticResource datagridElemStyle}"
...
/>
Good news is you can define the style on a derived element, like a TextBlock, and benefit from their properties:
<Style x:Key="datagridElemStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>

Resources