如何在wpf中的Headered Content Control的内容部分上显示错误消息

时间:2013-02-21 12:01:40

标签: wpf wpf-controls

我正在研究wpf应用程序。我对wpf很新。我使用“Headered Content Control”,标签作为标题,文本框作为内容部分。没问题。对于验证,我使用“IDataErrorInfo”。我能够显示错误,但我的问题是

i)错误边框显示在完整的Headered Contentcontrol上(在Label& On Tet Box上),如何仅在TextBox上显示红色边框...

ii)当我将光标放在边框上时,我能够显示错误信息(如图中所示),但是当我将光标放在文本框上时无法显示错误信息..... 任何人都可以帮助我如何更改样式,以便我可以在文本框工具提示上显示错误消息...

这是我正在显示错误消息的样式......

<Style TargetType="HeaderedContentControl">
        <Style.Setters>
<Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <!--<Border BorderBrush="Red" 
                                BorderThickness="1" 
                                ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                            <AdornedElementPlaceholder Name="customAdorner" />
                        </Border>-->
                        <AdornedElementPlaceholder Name="customAdorner" 
                                                   VerticalAlignment="Center" 
                                                   ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                            <Border BorderBrush="red" 
                                    BorderThickness="1">                                
                            </Border> 
                        </AdornedElementPlaceholder>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
 </Style.Setters>
    </Style>

enter image description here

先谢谢

我的Headered内容控制代码是:

 <HeaderedContentControl Header="Name" 
   Content="{Binding Path=ValidationClassProp.Name, Mode=TwoWay, ValidatesOnDataErrors=True}"/>

验证类继承IDataErrorInfo ...

2 个答案:

答案 0 :(得分:0)

由于验证错误模板设置为在整个控件上显示,因此您只需调整数据模板上的绑定,以便验证错误模板显示在模板内的TextBlock上,而不是整个HeaderedContentControl。

我构建了一个小应用来证明这一点。这是代码:

Window的XAML

<Window x:Class="_15001777.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:_15001777"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <ItemsControl ItemsSource="{Binding Path=Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type local:HeaderedItem}">
                    <HeaderedContentControl Header="{Binding Path=Header}">
                        <HeaderedContentControl.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Label VerticalAlignment="Center"
                                           HorizontalContentAlignment="Right"
                                           Content="Name" />
                                    <TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=HeaderedContentControl}, Path=DataContext.Header, ValidatesOnDataErrors=True}" />
                                </StackPanel>
                            </DataTemplate>
                        </HeaderedContentControl.HeaderTemplate>
                    </HeaderedContentControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

Window的代码隐藏

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace _15001777
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Items = new ObservableCollection<object>();
            Items.Add(new HeaderedItem { Header = "One" });
        }

        public ObservableCollection<object> Items { get; private set; } 
    }

    public class HeaderedItem : IDataErrorInfo
    {
        public object Header { get; set; }

        public string this[string columnName]
        {
            get { return columnName == "Header" ? "There was an error!" : null; }
        }

        public string Error { get; private set; }
    }
}

答案 1 :(得分:0)

您遇到的问题是由于您将HeaderedContentControl的内容属性绑定到模型中的属性。在这种情况下,整个HeaderedContentControl被视为错误

因此,可能的解决方案是明确指定HeaderedContentControl的内容和Text控件的TextBox属性的绑定

<HeaderedContentControl Header="Name">
    <TextBox Text="{Binding Path=ValidationClassProp.Name, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
</HeaderedContentControl>

并在TextBox

的样式中应用您的错误模板

修改

有一个粗略的想法,试图保持你当前的xaml。 您可以尝试创建IValueConveter,将AdornedElementPlaceholder作为值,将其转换为HeaderedContentControl并尝试获取此控件的内容部分的实际大小和位置,然后准备{{1}结构并将其作为结果返回。您的红色边框ThinknessThinkness 所以它应该是这样的:

Margin

同样,这不是一个完整的解决方案,而是一个可能的方向,因为它仍然不容易获得内容部分的位置......