1

私はwpfアプリケーションに取り組んでいます。私はwpfを初めて使用します。「ヘッダー付きコンテンツコントロール」、ヘッダーとしてのラベル、コンテンツ部分としてのテキストボックスを使用しています。問題ありません。検証には「IDataErrorInfo」を使用しています。エラーを表示することはできますが、問題は

i)完全なヘッダー付きコンテンツコントロール(ラベルとテキストボックスの両方)にエラー境界線が表示されます。テキストボックスにのみ赤い境界線を表示するにはどうすればよいですか。

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>

ここに画像の説明を入力してください

前もって感謝します

私のヘッダー付きコンテンツコントロールコードは次のとおりです。

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

検証クラスがIDataErrorInfoを継承する場所...

4

2 に答える 2

0

検証エラーテンプレートはコントロール全体に表示されるように設定されているため、HeaderedContentControl全体ではなく、テンプレート内のTextBlockに検証エラーテンプレートが表示されるように、データテンプレートのバインディングを調整する必要があります。

これを実証するために小さなアプリを作成しました。コードは次のとおりです。

ウィンドウの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>

ウィンドウのコードビハインド

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; }
    }
}
于 2013-02-21T14:08:55.050 に答える
0

あなたが直面している問題は、コンテンツ プロパティをHeaderedContentControlモデルのプロパティにバインドしていることが原因です。この場合、全体がエラーHeaderedContentControl と見なされます

したがって、可能な解決策は、コンテンツを明示的に指定し、コントロールのプロパティにHeaderedContentControlバインドすることですTextTextBox

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

そして、あなたのエラーテンプレートをスタイリッシュに適用してくださいTextBox

編集

現在の xaml を維持しようとする大まかなアイデアがありました。IValueConveter値として受け取るものを作成してAdornedElementPlaceholderキャストしHeaderedContentControl、このコントロールのコンテンツ部分の実際のサイズと位置を取得してから、Thinkness構造体を準備して結果として返すことができます。それThinknessMarginあなたの赤い境界線の

<AdornedElementPlaceholder Name="customAdorner" 
    VerticalAlignment="Center"
    ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                        <Border BorderBrush="red"
                                Margin={Binding ElementName=customAdorner, Converter={StaticResource SomeCustomConverter}"
                                BorderThickness="1">                             
                        </Border> 
                    </AdornedElementPlaceholder>

繰り返しますが、これは完全な解決策ではなく、可能な方向性ではありません。コンテンツ部分の位置を取得するのはまだ簡単ではないためです...

于 2013-02-21T15:23:04.673 に答える