Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UserControl中的Binding Validation.ErrorTemplate_C#_Wpf_Validation_Xaml_Dependency Properties - Fatal编程技术网

C# UserControl中的Binding Validation.ErrorTemplate

C# UserControl中的Binding Validation.ErrorTemplate,c#,wpf,validation,xaml,dependency-properties,C#,Wpf,Validation,Xaml,Dependency Properties,我有一个用户控件,它有一个文本框,其中它的文本属性绑定到一个名为SelectedValue的依赖属性。当用户输入文本时,将根据另一个名为ItemsSource的DP验证该值,以查看它是否在其中。如果不是,我抛出一个错误。一切正常-当出现错误时,UC中的TB周围有默认的红色框 但我希望用户在创建UC实例时能够在XAML中指定ControlTemplate。所以我想我可以创建另一个类型为ControlTemplate的DP,它们可以绑定到。这似乎是可行的,但我如何在XAML中真正实现它呢?如果它执行

我有一个用户控件,它有一个文本框,其中它的文本属性绑定到一个名为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>
谢谢你的帮助

厄尼


更新:

谢谢各位。事实上,我试过阿迪和尼特的回答。这两种方法都有效,但Adi更接近于我所寻找的,不必定义用户控件本地的模板。即使我没有实际创建模板,只是添加了绑定,但设计器给出了一个错误,Nit也会运行。我确实需要对您的代码进行一些Adi调整,以便将其设置在文本框本身上:

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);
    }
}
谢谢

查看,您可以看到它的元数据属性设置为
true
,因此不幸的是,您无法将数据绑定到该属性

我相信您仍然可以处理依赖项属性的OnChanged事件,自己使用
验证来设置该属性。SetErrorTemplate()


据我所知,你不能用装订来做你想做的事。ErrorTemplate可与StaticResource一起使用。

由于ErrorTemplate是不可绑定的,您可以使用资源设置Validation.ErrorTemplate,并在DependencyPropertyChange中使用更新的值替换资源键

<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="{DynamicResource MyErrorTemplate}"
             >

您可以定义并绑定为静态资源:

例如:

<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 CookBook 4.5第232页中获取了这个示例,它非常有效

 public static readonly DependencyProperty ValidationTemplateProperty =
        DependencyProperty.Register("ValidationTemplate"
                                    , typeof(ControlTemplate)
                                    , typeof(AutoCompleteComboBox)
                                    , new FrameworkPropertyMetadata(new ControlTemplate(),ValidationTemplateChanged));

    private static void ValidationTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        AutoCompleteComboBox control = d as AutoCompleteComboBox;
        control.Resources["MyErrorTemplate"] = e.NewValue;
    }
<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>