ErrorTemplate 显示用户控件而不是其中的文本框!怎么修?
Posted
技术标签:
【中文标题】ErrorTemplate 显示用户控件而不是其中的文本框!怎么修?【英文标题】:ErrorTemplate showing for the user control and not the text box within it! How to fix? 【发布时间】:2013-09-14 16:19:20 【问题描述】:这里有与此类似的问题,但是我尝试了上述解决方案无济于事!
让我简单介绍一下设置 - 我有一个实现 IDataErrorInfo 的模型,一个将模型公开给视图的视图模型,在视图中我有一个用户控件,它只是一个带标签的文本框,模型属性绑定到用户控件的内部文本框通过依赖属性......并且一切都正确绑定,所有验证都被触发并返回正确的错误!但是,用户控件似乎正在拦截错误,因此显示的是用户控件的错误模板,而不是文本框。
所以,我知道我可以通过将属性设置为 x:Null 来阻止显示用户控件的错误模板,但是如何触发显示文本框的错误模板?!我已经尝试在用户控件中实现 IDataErrorInfo(如某些人所建议的那样)并在用户控件中明确定义验证错误模板,但我就是无法显示该死的东西。在这一点上,我认为用户控件只是拦截错误,抓住它而不将它传递到文本框,因此错误模板没有显示,因为它不知道错误。
过去一天我一直在拔头发,真的不想求助于不使用用户控件,因为我知道这可以实现,但我真的不知道如何解决它!因此,如果有任何巫师可以提供帮助,我将非常感激!
用户控件 XAML:
<UserControl x:Class="PIRS_Client.Control.LabelTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="40.541" Width="321.027">
<Grid Height="41" VerticalAlignment="Top" HorizontalAlignment="Left" Width="321">
<StackPanel Orientation="Horizontal" Margin="0,8,50,9">
<Label Content="Label" Height="28" Name="BaseLabel" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="116" FontSize="11" />
<TextBox Height="22" Width="100" Margin="0,0,0,0" x:Name="BaseTextBox" VerticalContentAlignment="Center" VerticalAlignment="Top" FontSize="11"/>
</StackPanel>
</Grid>
用户控制代码:
public partial class LabelTextBox : UserControl
public static readonly DependencyProperty TextBoxTextProperty = DependencyProperty.Register("TextBoxText", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata() BindsTwoWayByDefault = true );
public LabelTextBox()
InitializeComponent();
Binding textBoxText = new Binding("TextBoxText") Source = this, Mode = BindingMode.TwoWay ;
BaseTextBox.SetBinding(TextBox.TextProperty, textBoxText);
[Browsable(true)]
public string LabelText
get return BaseLabel.Content.ToString();
set
BaseLabel.Content = value;
[Browsable(true)]
public string TextBoxText
get return (string)GetValue(TextBoxTextProperty);
set SetValue(TextBoxTextProperty, value);
[Browsable(true)]
public double TextBoxWidth
get return BaseTextBox.Width;
set
BaseTextBox.Width = value;
查看 - 用户控件声明:
<control:LabelTextBox HorizontalAlignment="Left" LabelText="Email" TextBoxText="Binding UpdateSourceTrigger=LostFocus, Path=NewFosterCarerInfo.partner_email, ValidatesOnDataErrors=true, NotifyOnValidationError=true" TextBoxWidth="120" Margin="190,182,-61,0" VerticalAlignment="Top" Height="41" Width="321"/>
【问题讨论】:
您可以尝试通过子类化TextBox
来创建自定义控件,而不是创建用户控件
在你的用户控件中设置文本框绑定时也设置ValidatesOnDataErrors=true
@Shoe 我已经设置了 ValidatesOnDataErrors=true... 我希望那是我错过的,并且修复是那么简单!不过谢谢!
我在 <control:LabelTextBox..
的用法上看到了 ValidatesOnDataErrors=true
,但在控件本身的 xaml 定义或代码隐藏中没有看到
@Shoe 我怎么把它放在那里?除了在用户控件本身中声明文本绑定......这显然没有意义......对吧?!
【参考方案1】:
对于任何有我问题的人,这里是工作代码
用户控件 xaml:
<UserControl x:Class="PIRS_Client.Control.LabelTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="40.541" Width="321.027"
x:Name="Parent" Validation.ErrorTemplate="x:Null">
<Grid Height="41" VerticalAlignment="Top" HorizontalAlignment="Left" Width="321" DataContext="Binding ElementName=Parent, ValidatesOnDataErrors=True">
<StackPanel Orientation="Horizontal" Margin="0,8,50,9">
<Label Content="Label" Height="28" Name="BaseLabel" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="116" FontSize="11" />
<TextBox Height="22" Text="Binding Path=TextBoxText, ValidatesOnDataErrors=True" Width="100" Margin="0,0,0,0" x:Name="BaseTextBox" VerticalContentAlignment="Center" VerticalAlignment="Top" FontSize="11"/>
</StackPanel>
</Grid>
UserControl 后面的代码:
public partial class LabelTextBox : UserControl, IDataErrorInfo
public LabelTextBox()
InitializeComponent();
public static readonly DependencyProperty TextBoxTextProperty =
DependencyProperty.Register(
"TextBoxText",
typeof(string),
typeof(LabelTextBox),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);
#region IDataErrorInfo Members
public string Error
get
if (Validation.GetHasError(this))
return string.Join(Environment.NewLine, Validation.GetErrors(this).Select(e => e.ErrorContent));
return null;
public string this[string columnName]
get
// use a specific validation or ask for UserControl Validation Error
if (Validation.GetHasError(this))
var error = Validation.GetErrors(this).FirstOrDefault(e => ((BindingExpression)e.BindingInError).TargetProperty.Name == columnName);
if (error != null)
return error.ErrorContent as string;
return null;
#endregion
[Browsable(true)]
public string LabelText
get return BaseLabel.Content.ToString();
set BaseLabel.Content = value;
[Browsable(true)]
public string TextBoxText
get return (string)GetValue(TextBoxTextProperty);
set
SetValue(TextBoxTextProperty, value);
[Browsable(true)]
public double TextBoxWidth
get return BaseTextBox.Width;
set BaseTextBox.Width = value;
使用用户控件:
<control:LabelTextBox HorizontalAlignment="Left" LabelText="Email" TextBoxText="Binding Path=NewFosterCarerInfo.partner_email, ValidatesOnDataErrors=true" TextBoxWidth="120" Margin="190,182,-61,0" VerticalAlignment="Top" Height="41" Width="321"/>
如果你想要一个不错的 Validation.ErrorTemplate:
`<Style TargetType="x:Type TextBox">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,2,40,2" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="true">
<Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent">
<TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
</TextBlock>
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>`
【讨论】:
以上是关于ErrorTemplate 显示用户控件而不是其中的文本框!怎么修?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 WPF 中扩展控件以便为 ErrorTemplate 中的错误消息腾出空间?
浏览器控件 NavigateToString 显示 HTML 代码而不是渲染页面
有关如何使用软按钮而不是物理音量控件显示 Chromecast 音量滑块的示例代码
托管 WebBrowser 控件尝试下载 Flash 内容而不是播放它