3

テキスト プロパティが SelectedValue という依存関係プロパティにバインドされているテキスト ボックスを持つユーザー コントロールがあります。ユーザーがテキストを入力すると、その値が ItemsSource という別の DP に対して検証され、そこにあるかどうかが確認されます。そうでない場合は、エラーをスローします。すべてが機能します。エラーが発生した場合、UC の TB にはデフォルトの赤いボックスが表示されます。

しかし、UC のインスタンスを作成するときに、ユーザーが XAML で ControlTemplate を指定できるようにしたいと考えています。そのため、タイプ ControlTemplate の別の DP を作成して、それらをバインドできると考えました。これは機能しているように見えますが、実際に XAML で実装するにはどうすればよいですか? 次のようなことをする場合:

Validation.ErrorTemplate="{Binding ValidationTemplate}"

「'ErrorTemplate' プロパティをデータバインドできません」というエラーがスローされます。以下は、コードの関連部分です。

<Canvas DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
    ....
    <TextBox x:Name="ValueTextBox"
             TextWrapping="NoWrap" 
             GotFocus="_ValueTextBox_GotFocus"
             Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Canvas}}, Path=ActualWidth}"
             Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Canvas}}, Path=ActualHeight}"
       ----->Validation.ErrorTemplate="{Binding ValidationTemplate}"<-----
             >

        <TextBox.Resources>
            <CollectionViewSource x:Key="UniqueNamesList" Source="{Binding ItemsSource}" />
        </TextBox.Resources>

        <TextBox.Text>
            <Binding Path="SelectedValue" >
                <Binding.ValidationRules>
                    <l:InListValidator ValidationStep="RawProposedValue" 
                                       IgnoreCase="True" 
                                       UniqueNames="{StaticResource UniqueNamesList}" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    ....
</Canvas>

および DP 自体:

public object ValidationTemplate
{
    get { return (ControlTemplate)GetValue(ValidationTemplateProperty); }
    set { SetValue(ValidationTemplateProperty, value); }
}
public static readonly DependencyProperty ValidationTemplateProperty =
    DependencyProperty.Register("ValidationTemplate"
                                , typeof(ControlTemplate)
                                , typeof(AutoCompleteComboBox)
                                , new FrameworkPropertyMetadata(new ControlTemplate()));

助けてくれてありがとう。

アーニー


アップデート:

みんなありがとう。私は実際に Adi と Nit の両方の応答を試しました。どちらも機能しましたが、Adi は、ユーザー コントロールにローカルなテンプレートを定義する必要がないため、私が探していたものに近かったです。実際にテンプレートを作成せずにバインディングを追加しただけでも、Nit は実際に実行されますが、デザイナーはエラーを出します。TextBox 自体に設定するために、コードを少し調整する必要がありました。

public ControlTemplate ValidationTemplate
{
    get { return (ControlTemplate)GetValue(ValidationTemplateProperty); }
    set { SetValue(ValidationTemplateProperty, value); }
}
public static readonly DependencyProperty ValidationTemplateProperty =
    DependencyProperty.Register("ValidationTemplate"
                                , typeof(ControlTemplate)
                                , typeof(AutoCompleteComboBox)
                                , new FrameworkPropertyMetadata(new ControlTemplate(), OnValidationTemplateChanged));

private static void OnValidationTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue != null)
    {
        AutoCompleteComboBox control = (AutoCompleteComboBox)d;
        Validation.SetErrorTemplate(control.ValueTextBox, (ControlTemplate)e.NewValue);
    }
}

ありがとう!

4

4 に答える 4

0

静的リソースとして定義およびバインドできます。

例:

<Window.Resources>
    <ControlTemplate x:Key="errorTemplate">
        <Border BorderBrush="Red" BorderThickness="2">
            <Grid>
                <AdornedElementPlaceholder x:Name="_el" />
                <TextBlock Text="{Binding [0].ErrorContent}"
                           Foreground="Red" HorizontalAlignment="Right"
                           VerticalAlignment="Center" Margin="0,0,6,0"/>
            </Grid>
        </Border>
    </ControlTemplate>
</Window.Resources>

要素内:

    <TextBox Grid.Column="1" Margin="6" Validation.ErrorTemplate="{StaticResource errorTemplate}">
        <TextBox.Text>
            <Binding Path="Name" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged" >
                <Binding.ValidationRules>
                    <local:MinCharsRule MinimumChars="3" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

注: この例は WPF Coo​​kBook 4.5 Page 232 から引用したもので、うまく機能します。

于 2016-03-30T22:46:25.497 に答える