0

検証をトリガーするために INotifyDataErrorInfo を使用しています。

Validation.ErrorTemplate からコントロールを取得できません。その高さを装飾された要素の下マージンに追加して、装飾された要素の下にエラーが表示され、下のコントロールが下に移動するようにするには、スタックパネルの実際の高さが必要です。

コンバーター内でビジュアル ツリーを使用しようとしましたが、何も起こりません。また、XAML を使用してみましたが、まだ何もありません。

<converters:ErrorsToMarginMultiConverter x:Key="ErrorsToMarginMultiConverter"/>
    <Style TargetType="{x:Type Control}" x:Key="ValidationStyle">
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Height" Value="25"/>
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel>
                        <!--The Original Control-->
                        <AdornedElementPlaceholder x:Name="OriginalControl"/>
                        <!--The Errors List-->
                        <ItemsControl ItemsSource="{Binding}" x:Name="ErrorItemsControl">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <BulletDecorator Width="{Binding ElementName=OriginalControl, Path=ActualWidth, UpdateSourceTrigger=PropertyChanged}">
                                        <BulletDecorator.Bullet>
                                            <Ellipse Fill="Red" Width="5" Height="5"/>
                                        </BulletDecorator.Bullet>
                                        <TextBlock Text="{Binding ErrorContent, StringFormat=' {0}'}" Foreground="Red" TextWrapping="Wrap"/>
                                    </BulletDecorator>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="BorderBrush" Value="DarkRed" />
                <Setter Property="Margin">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource ErrorsToMarginMultiConverter}" UpdateSourceTrigger="PropertyChanged">
                            <Binding Path="(Validation.Errors)" RelativeSource="{RelativeSource Self}"/>
                            <Binding RelativeSource="{RelativeSource Self}"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

検証エラー テンプレート内のコントロールを何らかの形でコンバーターへのパラメーターとして取得するか、実際の高さを抽出するためにコンバーター内のコードでそれらを取得することを期待しています。

このテンプレートでデフォルトで何が起こっているかを次に示します。これ が期待される結果です

検証エラーが発生したときに期待される結果を得るために、元のコントロール (TextBox) に下マージンとして追加するために、そのスタックパネルの高さを取得したいと考えています。 ツリー ビュー コンバーターのコード サンプル

編集:私は部分的な解決策を見つけることができました、

public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                var adornedElement = value[1] as Control;
                var adornerLayer = System.Windows.Documents.AdornerLayer.GetAdornerLayer(adornedElement);
                var templatedAdorner = adornerLayer.GetAdorners(adornedElement);

                var margin = adornedElement.Margin;
                margin.Bottom = 20;

                if (templatedAdorner != null && templatedAdorner.Length > 0)
                    margin.Bottom = templatedAdorner[0].ActualHeight;

                return margin;
            }

            return value;
        }

問題は、このコンバーターが 2 回トリガーされることです。1 回目は以前の検証エラーをクリアするとき、2 回目はエラーを追加するときです。初めて templatedAdorner を見つけて読み取るのは、実際の高さです。しかし、2 回目は adorner レイヤーが見つかったが、templatedAdorned が存在しない場合 (null)。私のビジュアルツリーでは、それらを見ることができます。また、ビューには正しく表示されますが、検証エラーの数も正しくありません。

トリガーは ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); です。INotifyDataErrorInfo から。

4

0 に答える 0