I have a custom edit item template. I am trying to show the error for a tree item that should not be selected. The error is created in the custom appointment class, however there is no red box showing the error for the radtreeview. I know the error is present because the okay button is greyed out when selecting an invalid item from the tree.
<
telerik:RadTreeView
x:Name
=
"TreeView"
telerik:TextSearch.TextPath
=
"OrgName"
ToolKit:DockPanel.Dock
=
"Top"
IsEnabled
=
"{Binding IsReadOnly, Converter={StaticResource InvertedBooleanConverter}}"
telerik:StyleManager.Theme
=
"{StaticResource Theme}"
SelectionMode
=
"Single"
BorderThickness
=
"1"
ItemTemplate
=
"{StaticResource OrgItemTemplate}"
ItemsSource
=
"{Binding Source={StaticResource CalViewModel}, Path=Organizations, Mode=TwoWay, Converter={StaticResource OrgHierarchyConverter}}"
ItemContainerStyle
=
"{StaticResource OrgTreeViewItemStyle}"
SelectedItem
=
"{Binding Occurrence.Appointment.OrganizationPoco, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}"
Loaded
=
"TreeViewLoaded"
/>
private string ValidateOrganizationPoco()
{
return "I AM AN ERROR";
}
Thank you,
Craig
3 Answers, 1 is accepted
The RadTreeView control doesn't support data validation out-of-the-box. This is why the control has no way of detecting when a value is invalid and it also doesn't have any validation states. This is why you see no validation border.
In order to implement a validation in the RadTreeViewItems, you'll need to make it manually. This implementation strongly depends on your scenario and logic, but if you're validating a TextBox input during the edit state of the RadTreeViewItem, you can validate the TextBox and cancel the edit completion until the entered value is valid. However in case your scenario is different, if you can send over a sample solution demonstrating it, we will be able to suggest more suitable approaches.
Kind regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Craig,
I had the same issue and solve the problem by altering the default template for the RadTreeView and adding inserting the ValidationStates block found in the default TextBox template. I found this article that says you need only define the validation VisualStateGroup, a validation visual in the template, and the appropriate ValidationToolTipTemplate. Judging from how simple the solution is, we can resonably assume that Silverlight's internal validation mechanisms will do the rest. See the template below as an example.
Example use case (NOTE: pay attention to the SelectedValue binding)
<
t:RadTreeView
x:Name
=
"idTree"
Style
=
"{StaticResource keyRadTreeViewStyle001}"
Foreground
=
"{Binding Path=Foreground, Mode=OneWay, ElementName=idHost}"
ItemContainerStyle
=
"{StaticResource keyRadTreeViewItemStyle_DialogWindow}"
VerticalAlignment
=
"Top"
Grid.Row
=
"1"
BorderThickness
=
"0"
IsLoadOnDemandEnabled
=
"True"
SelectedValuePath
=
"ID"
LoadOnDemand
=
"RadTreeView_LoadOnDemand"
IsDragDropEnabled
=
"False"
SelectionMode
=
"Single"
IsSingleExpandPath
=
"True"
IsExpandOnSingleClickEnabled
=
"True"
IsExpandOnDblClickEnabled
=
"True"
SelectedValue
=
"{Binding Path=Target.ParentID, Mode=TwoWay, ElementName=idHost, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}"
Margin
=
"{StaticResource keyCommonMargin}"
ItemsSource
=
"{Binding Path=TreeItemsSource, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ctr:CreateContainerUC}}"
ItemTemplate
=
"{StaticResource keyTreeNodeLevel0}"
/>
The new TreeView style with the validation template. (NOTE: this is the bare minimum for this to work and keep the visualizatoins that Telerik programed into their control).
<
Style
x:Key
=
"keyRadTreeViewStyle001"
TargetType
=
"t:RadTreeView"
>
<
Setter
Property
=
"Template"
>
<
Setter.Value
>
<
ControlTemplate
TargetType
=
"t:RadTreeView"
>
<
Grid
x:Name
=
"RootElement"
>
<
Grid.Resources
>
<
ControlTemplate
x:Key
=
"ValidationToolTipTemplate"
>
<
Grid
x:Name
=
"Root"
Margin
=
"5,0"
Opacity
=
"0"
RenderTransformOrigin
=
"0,0"
>
<
Grid.RenderTransform
>
<
TranslateTransform
x:Name
=
"xform"
X
=
"-25"
/>
</
Grid.RenderTransform
>
<
VisualStateManager.VisualStateGroups
>
<
VisualStateGroup
x:Name
=
"OpenStates"
>
<
VisualStateGroup.Transitions
>
<
VisualTransition
GeneratedDuration
=
"0"
/>
<
VisualTransition
GeneratedDuration
=
"0:0:0.2"
To
=
"Open"
>
<
Storyboard
>
<
DoubleAnimation
Duration
=
"0:0:0.2"
To
=
"0"
Storyboard.TargetProperty
=
"X"
Storyboard.TargetName
=
"xform"
>
<
DoubleAnimation.EasingFunction
>
<
BackEase
Amplitude
=
".3"
EasingMode
=
"EaseOut"
/>
</
DoubleAnimation.EasingFunction
>
</
DoubleAnimation
>
<
DoubleAnimation
Duration
=
"0:0:0.2"
To
=
"1"
Storyboard.TargetProperty
=
"Opacity"
Storyboard.TargetName
=
"Root"
/>
</
Storyboard
>
</
VisualTransition
>
</
VisualStateGroup.Transitions
>
<
VisualState
x:Name
=
"Closed"
>
<
Storyboard
>
<
DoubleAnimation
Duration
=
"0"
To
=
"0"
Storyboard.TargetProperty
=
"Opacity"
Storyboard.TargetName
=
"Root"
/>
</
Storyboard
>
</
VisualState
>
<
VisualState
x:Name
=
"Open"
>
<
Storyboard
>
<
DoubleAnimation
Duration
=
"0"
To
=
"0"
Storyboard.TargetProperty
=
"X"
Storyboard.TargetName
=
"xform"
/>
<
DoubleAnimation
Duration
=
"0"
To
=
"1"
Storyboard.TargetProperty
=
"Opacity"
Storyboard.TargetName
=
"Root"
/>
</
Storyboard
>
</
VisualState
>
</
VisualStateGroup
>
</
VisualStateManager.VisualStateGroups
>
<
Border
Background
=
"#052A2E31"
CornerRadius
=
"5"
Margin
=
"4,4,-4,-4"
/>
<
Border
Background
=
"#152A2E31"
CornerRadius
=
"4"
Margin
=
"3,3,-3,-3"
/>
<
Border
Background
=
"#252A2E31"
CornerRadius
=
"3"
Margin
=
"2,2,-2,-2"
/>
<
Border
Background
=
"#352A2E31"
CornerRadius
=
"2"
Margin
=
"1,1,-1,-1"
/>
<
Border
Background
=
"#FFDC000C"
CornerRadius
=
"2"
/>
<
Border
CornerRadius
=
"2"
>
<
TextBlock
Foreground
=
"White"
MaxWidth
=
"250"
Margin
=
"8,4,8,4"
TextWrapping
=
"Wrap"
Text
=
"{Binding (Validation.Errors)[0].ErrorContent}"
UseLayoutRounding
=
"false"
/>
</
Border
>
</
Grid
>
</
ControlTemplate
>
<
t:Windows8Theme
x:Key
=
"Theme"
/>
<
SolidColorBrush
x:Key
=
"DragBetweenItemsFeedback_BackgroundBrush"
Color
=
"#FFFA8C3B"
/>
</
Grid.Resources
>
<
VisualStateManager.VisualStateGroups
>
<
VisualStateGroup
x:Name
=
"DropStates"
>
<
VisualState
x:Name
=
"DropImpossible"
/>
<
VisualState
x:Name
=
"DropPossible"
/>
<
VisualState
x:Name
=
"DropRootPossible"
>
<
Storyboard
>
<
ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty
=
"Background"
Storyboard.TargetName
=
"ScrollViewer"
>
<
DiscreteObjectKeyFrame
KeyTime
=
"0"
>
<
DiscreteObjectKeyFrame.Value
>
<
SolidColorBrush
Color
=
"#7fFCD590"
/>
</
DiscreteObjectKeyFrame.Value
>
</
DiscreteObjectKeyFrame
>
</
ObjectAnimationUsingKeyFrames
>
</
Storyboard
>
</
VisualState
>
</
VisualStateGroup
>
<
VisualStateGroup
x:Name
=
"ValidationStates"
>
<
VisualState
x:Name
=
"Valid"
/>
<
VisualState
x:Name
=
"InvalidUnfocused"
>
<
Storyboard
>
<
ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty
=
"Visibility"
Storyboard.TargetName
=
"ValidationErrorElement"
>
<
DiscreteObjectKeyFrame
KeyTime
=
"0"
>
<
DiscreteObjectKeyFrame.Value
>
<
Visibility
>Visible</
Visibility
>
</
DiscreteObjectKeyFrame.Value
>
</
DiscreteObjectKeyFrame
>
</
ObjectAnimationUsingKeyFrames
>
</
Storyboard
>
</
VisualState
>
<
VisualState
x:Name
=
"InvalidFocused"
>
<
Storyboard
>
<
ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty
=
"Visibility"
Storyboard.TargetName
=
"ValidationErrorElement"
>
<
DiscreteObjectKeyFrame
KeyTime
=
"0"
>
<
DiscreteObjectKeyFrame.Value
>
<
Visibility
>Visible</
Visibility
>
</
DiscreteObjectKeyFrame.Value
>
</
DiscreteObjectKeyFrame
>
</
ObjectAnimationUsingKeyFrames
>
<
ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty
=
"IsOpen"
Storyboard.TargetName
=
"validationTooltip"
>
<
DiscreteObjectKeyFrame
KeyTime
=
"0"
xmlns:System
=
"clr-namespace:System;assembly=mscorlib"
>
<
DiscreteObjectKeyFrame.Value
>
<
System:Boolean
>True</
System:Boolean
>
</
DiscreteObjectKeyFrame.Value
>
</
DiscreteObjectKeyFrame
>
</
ObjectAnimationUsingKeyFrames
>
</
Storyboard
>
</
VisualState
>
</
VisualStateGroup
>
</
VisualStateManager.VisualStateGroups
>
<
Border
BorderBrush
=
"{TemplateBinding BorderBrush}"
BorderThickness
=
"{TemplateBinding BorderThickness}"
Background
=
"{TemplateBinding Background}"
>
<
Grid
>
<
ScrollViewer
x:Name
=
"ScrollViewer"
BorderThickness
=
"0"
Background
=
"{x:Null}"
t:ScrollViewerExtensions.EnableMouseWheel
=
"True"
IsTabStop
=
"False"
Padding
=
"{TemplateBinding Padding}"
t:StyleManager.Theme
=
"{StaticResource Theme}"
>
<
ItemsPresenter
/>
</
ScrollViewer
>
<
Grid
x:Name
=
"DragBetweenItemsFeedback"
HorizontalAlignment
=
"Left"
Height
=
"8"
IsHitTestVisible
=
"False"
Margin
=
"{TemplateBinding Padding}"
Visibility
=
"Collapsed"
VerticalAlignment
=
"Top"
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"8"
/>
<
ColumnDefinition
/>
</
Grid.ColumnDefinitions
>
<
Ellipse
HorizontalAlignment
=
"Left"
Height
=
"8"
Stroke
=
"{StaticResource DragBetweenItemsFeedback_BackgroundBrush}"
StrokeThickness
=
"2"
VerticalAlignment
=
"Center"
Width
=
"8"
/>
<
Rectangle
Grid.Column
=
"1"
Fill
=
"{StaticResource DragBetweenItemsFeedback_BackgroundBrush}"
Height
=
"2"
Margin
=
"-2,3,0,0"
RadiusY
=
"2"
RadiusX
=
"2"
VerticalAlignment
=
"Top"
/>
</
Grid
>
<
Border
x:Name
=
"ValidationErrorElement"
BorderBrush
=
"#FFDB000C"
BorderThickness
=
"1"
CornerRadius
=
"1"
Visibility
=
"Collapsed"
>
<
ToolTipService.ToolTip
>
<
ToolTip
x:Name
=
"validationTooltip"
DataContext
=
"{Binding RelativeSource={RelativeSource TemplatedParent}}"
Placement
=
"Right"
PlacementTarget
=
"{Binding RelativeSource={RelativeSource TemplatedParent}}"
Template
=
"{StaticResource ValidationToolTipTemplate}"
>
<
ToolTip.Triggers
>
<
EventTrigger
RoutedEvent
=
"Canvas.Loaded"
>
<
BeginStoryboard
>
<
Storyboard
>
<
ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty
=
"IsHitTestVisible"
Storyboard.TargetName
=
"validationTooltip"
>
<
DiscreteObjectKeyFrame
KeyTime
=
"0"
xmlns:System
=
"clr-namespace:System;assembly=mscorlib"
>
<
DiscreteObjectKeyFrame.Value
>
<
System:Boolean
>true</
System:Boolean
>
</
DiscreteObjectKeyFrame.Value
>
</
DiscreteObjectKeyFrame
>
</
ObjectAnimationUsingKeyFrames
>
</
Storyboard
>
</
BeginStoryboard
>
</
EventTrigger
>
</
ToolTip.Triggers
>
</
ToolTip
>
</
ToolTipService.ToolTip
>
<
Grid
Background
=
"Transparent"
HorizontalAlignment
=
"Right"
Height
=
"12"
Margin
=
"1,-4,-4,0"
VerticalAlignment
=
"Top"
Width
=
"12"
>
<
Path
Data
=
"M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"
Fill
=
"#FFDC000C"
Margin
=
"1,3,0,0"
/>
<
Path
Data
=
"M 0,0 L2,0 L 8,6 L8,8"
Fill
=
"#ffffff"
Margin
=
"1,3,0,0"
/>
</
Grid
>
</
Border
>
</
Grid
>
</
Border
>
</
Grid
>
</
ControlTemplate
>
</
Setter.Value
>
</
Setter
>
</
Style
>
I forgot to explain how I got the validation template info and to point out that I've tested this only with Silverlight 5 projects:
1. Open Expression blend
2. Drop a TextBox in the main page/user control
3. Create a copy of its Template
4. Copy the VisualStateGroup element named 'ValidationStates' from the template
5. Copy the Border named 'ValidationErrorElement' from the template
6. Copy the 'ValidationToolTipTemplate' ControlTemplate from above the template.
Hope this helps.
- Rashad Rivera