我在stackoverflow上的读者比写作者更多,但是我对此很绝望地回答问题。到目前为止我找到的解决方案无法解决我的问题: 虽然在以下Window-code中验证并显示TextBox的正确ErrorTemplate(绑定后面的ViewModel实现了INotifyDataErrorInfo),但TextBox完全相同的代码移动到自定义用户控件(控件:LabeledTextField),赢得了#39 ;吨
<Window x:Class="ValidationErrorTemplateTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.galasoft.ch/ignore"
xmlns:controls="clr-namespace:ValidationErrorTemplateTest"
mc:Ignorable="d ignore"
Height="300"
Width="300"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<StackPanel>
<TextBox Width="100" Height="20" Text="{Binding WelcomeTitle, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True}" Validation.ErrorTemplate="{StaticResource validationErrorHint}" Margin="40"/>
<controls:LabeledTextField Value="{Binding WelcomeTitle}"/>
</StackPanel>
</Grid>
外观/ MainSkin.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="validationErrorHint">
<DockPanel LastChildFill="True">
<Border Background="Red" DockPanel.Dock="Right" Margin="5,0,0,0" Width="12" Height="12" CornerRadius="6"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}">
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" FontSize="10"/>
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</ResourceDictionary>
这是LabeledTextField的xaml:
<UserControl x:Class="ValidationErrorTemplateTest.LabeledTextField"
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"
d:DesignHeight="30" d:DesignWidth="340">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="Root">
<TextBox Width="100" Height="20" Text="{Binding Value, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True}" Validation.ErrorTemplate="{StaticResource validationErrorHint}"/>
</Grid>
和代码隐藏:
namespace ValidationErrorTemplateTest
{
public partial class LabeledTextField : UserControl
{
public LabeledTextField()
{
InitializeComponent();
Root.DataContext = this;
}
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextField), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
}
}
我读过有关添加<ArdornerDecorator>
- 图层的内容,但它似乎无法解决问题。
我假设使用了usercontrol的ErrorTemplate而不是在usercontrol中分配给TextBox的ErrorTemplate,但我不知道如何解决这个问题。任何提示都会非常感激!
答案 0 :(得分:0)
我能够做到这一点。我刚刚使用了您粘贴的代码并制作了我的应用程序版本。
我的MainWindow
:
<Window x:Class="ErrorTemplateNotWorking.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ErrorTemplateNotWorking"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<StackPanel>
<TextBox Width="100" Height="20"
Text="{Binding WelcomeTitle, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Validation.ErrorTemplate="{StaticResource validationErrorHint}"
Margin="40"/>
<local:LabeledTextField Value="{Binding WelcomeTitle, ValidatesOnDataErrors=True}"
Width="100" Height="20"
Validation.ErrorTemplate="{StaticResource validationErrorHint}" />
</StackPanel>
</Grid>
</Window>
请注意,我只在绑定中使用ValidatesOnDataErrors=True
,我也为Validation.ErrorTemplate="{StaticResource validationErrorHint}"
设置了UserControl
。另一个重要的事情是为Width
设置Height
和UserControl
,这样验证感叹号就无法超出窗口的范围,因为控件只会在没有这个的情况下伸展到最大宽度。
我MainWindow
的代码隐藏:
namespace ErrorTemplateNotWorking
{
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Annotations;
public class MainWindowViewModel : IDataErrorInfo, INotifyPropertyChanged
{
public string this[string columnName]
{
get {
if (columnName == nameof(WelcomeTitle))
{
if (string.IsNullOrEmpty(WelcomeTitle) || WelcomeTitle.Length < 5)
{
return "Title should be at least 5 characters long";
}
}
return "";
}
}
public string Error => null;
private string _welcomeTitle;
public string WelcomeTitle
{
get { return _welcomeTitle; }
set
{
_welcomeTitle = value;
OnPropertyChanged(nameof(WelcomeTitle));
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
}
请注意,我使用了一些ReSharper和C#6功能,但要点应该是可以理解的。基本上我只是将DataContext设置为VM,而在VM中我使用验证规则实现IDataErrorInfo
,文本的长度至少应为5个字符。
MainSkin.xaml是一样的。
UserControl XAML:
<UserControl x:Class="ErrorTemplateNotWorking.LabeledTextField"
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"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="Root">
<TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</UserControl>
在Binding
,我甚至不需要任何额外的东西。
结果是:
我希望这会有所帮助。