我创建了一个由Telerik RadMaskedInput和Label组成的用户控件。用户控件是一个浮动标签输入,如下所示: http://css-tricks.com/float-labels-css/ 我遇到的问题是,当控件验证时,整个控件获得红色验证边框。我只需要RadMaskedInput框边框为红色。我已经看过其他几个帖子并帮助解决同一问题,但我似乎无法为我工作。我控制的XAML看起来像这样:
<Grid>
<Label x:Name="controlLabel"
VerticalAlignment="Bottom"
Padding="5,0,5,0"
HorizontalAlignment="Left"
Background="White"
Grid.Row="0"
Margin="10,0,0,0"
Panel.ZIndex="1"
IsHitTestVisible="False"
Template="{DynamicResource LabelControlTemplate1}"
Content="{Binding ElementName=floatingLabelTextBox, Path=LabelContent}"
FontFamily="{Binding ElementName=floatingLabelTextBox, Path=LabelFontFamily}"
FontSize="{Binding ElementName=floatingLabelTextBox, Path=LabelFontSize}"
Foreground="{DynamicResource FloatingLabelTextBox.Label.Foreground}"/>
<telerik:RadMaskedTextInput x:Name="controlMaskedTextBox"
Mask=""
TextMode="PlainText"
FontWeight="Normal"
BorderBrush="{DynamicResource FloatingLabelTextBox.BorderBrush}"
BorderThickness="1"
SelectionOnFocus="SelectAll"
IsClearButtonVisible="False"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
HorizontalContentAlignment="Right"
VerticalContentAlignment="Center"
Value="{Binding TextBoxText,
Mode=TwoWay,
UpdateSourceTrigger=LostFocus,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
NotifyOnValidationError=True}"
GotFocus="TextBox_GotFocus"
LostFocus="TextBox_LostFocus"
Template="{DynamicResource RadMaskedTextInputControlTemplate1}"/>
</Grid>
RadMaskedTextInput的控件模板如下所示:
<ControlTemplate x:Key="RadMaskedTextInputControlTemplate1" TargetType="{x:Type telerik:RadMaskedTextInput}">
<Grid SnapsToDevicePixels="True" UseLayoutRounding="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ClearButton"/>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="GridContainer">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#5EC9C9C9"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledVisual">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>-->
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisplayText">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF8D8D8D"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF8D8D8D"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisplayTextContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusedVisual">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>-->
</Storyboard>
</VisualState>
<VisualState x:Name="NotFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisplayTextContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="EditorSite">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Transparent"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ContentStates">
<VisualState x:Name="NotEmpty"/>
<VisualState x:Name="Empty">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisplayTextContent"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EmptyContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="True">
<Grid x:Name="GridContainer">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<MaskedInput:PreviewInputTextBox x:Name="EditorSite" AcceptsReturn="{TemplateBinding AcceptsReturn}" Cursor="{TemplateBinding Cursor}" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" Height="{TemplateBinding Height}" IsReadOnly="{TemplateBinding IsReadOnly}" IsEnabled="{TemplateBinding IsEnabled}" MaskedInputControl="{x:Null}" Padding="{TemplateBinding Padding}" Style="{TemplateBinding TextBoxStyle}" TabIndex="{TemplateBinding TabIndex}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<MaskedInput:PreviewInputTextBox.TextAlignment>
<Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<MaskedInput:HorizontalContentAlignmentToTextAlignmentConverter/>
</Binding.Converter>
</Binding>
</MaskedInput:PreviewInputTextBox.TextAlignment>
</MaskedInput:PreviewInputTextBox>
<Border x:Name="DisplayTextContent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" IsHitTestVisible="False" Visibility="Collapsed">
<MaskedInput:PreviewInputTextBox x:Name="DisplayText" Cursor="{TemplateBinding Cursor}" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Height="{TemplateBinding Height}" IsTabStop="False" IsReadOnly="{TemplateBinding IsReadOnly}" IsEnabled="{TemplateBinding IsEnabled}" MaskedInputControl="{x:Null}" Padding="{TemplateBinding Padding}" Style="{TemplateBinding TextBoxStyle}" Text="{Binding Text, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<MaskedInput:PreviewInputTextBox.TextAlignment>
<Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<MaskedInput:HorizontalContentAlignmentToTextAlignmentConverter/>
</Binding.Converter>
</Binding>
</MaskedInput:PreviewInputTextBox.TextAlignment>
</MaskedInput:PreviewInputTextBox>
</Border>
<Border x:Name="EmptyContent" IsHitTestVisible="False" Padding="5,0,0,0" Visibility="Collapsed">
<ContentControl x:Name="Content" ContentTemplate="{TemplateBinding EmptyContentTemplate}" Content="{TemplateBinding EmptyContent}" Foreground="{TemplateBinding Foreground}" FontStyle="Italic" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<telerik:RadButton x:Name="ClearButton" Grid.Column="1" Command="{TemplateBinding ClearCommand}" IsTabStop="False" InnerCornerRadius="3" Opacity="0" Style="{TemplateBinding ClearButtonStyle}">
<telerik:RadButton.Visibility>
<Binding Path="IsClearButtonVisible" RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<telerik:BooleanToVisibilityConverter/>
</Binding.Converter>
</Binding>
</telerik:RadButton.Visibility>
</telerik:RadButton>
</Grid>
</Border>
<!--<Border x:Name="FocusedVisual" BorderBrush="#FFFFC92B" BorderThickness="1" Background="{x:Null}" CornerRadius="5" Visibility="Collapsed"/>
<Border x:Name="DisabledVisual" BorderBrush="#FFD9D9D9" BorderThickness="1" CornerRadius="3" Visibility="Collapsed"/>-->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#FFD9D9D9"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
后面代码中的依赖项属性和dp回调:
public String TextBoxText
{
get
{
return (String)GetValue(TextBoxTextProperty);
}
set
{
SetValue(TextBoxTextProperty, value);
}
}
// Using a DependencyProperty as the backing store for TextBoxText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextBoxTextProperty =
DependencyProperty.Register("TextBoxText", typeof(String), typeof(FloatingLabelTextBox), new PropertyMetadata() { PropertyChangedCallback = UpdateTextBoxText });
private static void UpdateTextBoxText(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FloatingLabelTextBox control = d as FloatingLabelTextBox;
if (control != null && e.NewValue != null)
{
if (!string.IsNullOrWhiteSpace(e.NewValue as string))
{
control.FloatLabel();
}
else
{
control.DockLabel();
}
}
}
最后,我调用/使用控件的代码:
<controls:FloatingLabelTextBox LabelContent="Batch #"
TextBoxText="{Binding BatchNumber.StringValue,
Mode=TwoWay,
UpdateSourceTrigger=LostFocus,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
NotifyOnValidationError=True,
Converter={StaticResource stringToInt}}"
Validation.ErrorTemplate="{x:Null}"
LabelForeground="{DynamicResource FloatingLabelTextBox.Label.Foreground}"
LabelFontSize="12"
TextBoxWidth="150"
TextBoxHeight="30"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Grid.Row="1"
IsEnabled="{Binding BatchNumber.IsReadOnly, Mode=OneWay, Converter={StaticResource inverseBool}}" />
请注意,我正在使用MVVM模式。我已经从这里建模了我的代码:Validation Error Templates For UserControl但我没有看到预期的结果。我根本没有看到任何验证边界。
我在这个问题上花了太长时间。任何帮助/建议将不胜感激。
答案 0 :(得分:0)
我没有得到任何好的答案来解决这个问题。我尝试了所有我能想到的东西。我有信心这是可能的,但有一个截止日期,我需要得到一些东西。我的解决方案是重新控制控件,以便扩展基本控件。在这种情况下,我扩展了Telerik RadMaskedTextInput控件并覆盖了控件模板,将浮动标签添加到模板中,并使用一系列触发器来实现我所需要的。这允许我使用Telerik控件的本机验证,因此不必传递任何内容。对于我的情况,这可能是比创建用户控件更好的解决方案。如果需要更复杂的控制,我对如何完成这项工作没有好的建议,并希望看到评论或建议,以满足我的好奇心。感谢MethodMan花时间回应。