Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.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# TemplateBinding不处理ValidationRules依赖项属性_C#_Wpf_Xaml - Fatal编程技术网

C# TemplateBinding不处理ValidationRules依赖项属性

C# TemplateBinding不处理ValidationRules依赖项属性,c#,wpf,xaml,C#,Wpf,Xaml,我正在尝试创建cutom验证器控件,但不知道为什么ValidationRules上的Message属性要绑定到模板化父级。它可以运行,但每次都是空的。不知道为什么每次都是空的 可以找到示例项目 风格 <Style TargetType="{x:Type local:RequiredFieldBox}"> <Setter Property="Template"> <Setter.Value> <ControlTe

我正在尝试创建cutom验证器控件,但不知道为什么ValidationRules上的Message属性要绑定到模板化父级。它可以运行,但每次都是空的。不知道为什么每次都是空的

可以找到示例项目

风格

   <Style TargetType="{x:Type local:RequiredFieldBox}">
    <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type local:RequiredFieldBox}">
                <StackPanel Orientation="Vertical">

                    <TextBox>
                        <Binding  RelativeSource="{RelativeSource TemplatedParent}" Path="Text">
                        <Binding.ValidationRules>
                            <rule:RequiredFieldRule>
                                <rule:RequiredFieldRule.Params>
                                    <rule:ValidationParams 
                                        Message="{TemplateBinding Msg}"
                                        ValidationType="{TemplateBinding Type}"/>
                                </rule:RequiredFieldRule.Params>
                            </rule:RequiredFieldRule> 
                        </Binding.ValidationRules>
                    </Binding>
                        <TextBox.Style>
                    <Style TargetType="{x:Type TextBox}">
                      <Style.Triggers>
                           <Trigger Property="Validation.HasError" Value="true" >
                           <Setter Property="Foreground" Value="Red"/>
                           <Setter Property="Background" Value="MistyRose"/>
                           <Setter Property="BorderBrush" Value="Red"/>
                           <Setter Property="BorderThickness" Value="1.0"/>
                            <Setter Property="VerticalContentAlignment" Value="Center"/>
                           </Trigger>
                       </Style.Triggers>
                      <Setter Property="Validation.ErrorTemplate">
                         <Setter.Value>
                            <ControlTemplate>
                               <StackPanel>
                                  <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="40">
                                    <AdornedElementPlaceholder x:Name="Holder"/>
                                    <Image Height="{Binding Height, ElementName=Holder}" Width="20" Margin="10,0"
                                        Source="/Images/restricted.png" ToolTip="{Binding ElementName=Holder, 
                                        Path=AdornedElement.(Validation.Errors)
                     [0].ErrorContent}"/>
                                 </StackPanel>
                               </StackPanel>
                            </ControlTemplate>
                         </Setter.Value>
                    </Setter>
                 </Style>
             </TextBox.Style>
          </TextBox>
         </StackPanel>
        </ControlTemplate>
   </Setter.Value>
</Setter>
客户控制类

public class RequiredFieldBox : Control
{

    static RequiredFieldBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(RequiredFieldBox), new FrameworkPropertyMetadata(typeof(RequiredFieldBox)));
    }
    public static readonly DependencyProperty MsgProperty = DependencyProperty.Register(
     "Msg",
     typeof(string),
     typeof(RequiredFieldBox),
     new FrameworkPropertyMetadata(null)
   );
    public enum EnmValidationType
    {
        FieldNotEmpty,
        FieldNumeric,
        FieldIPAddress
    }
    public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type",
                                                                                         typeof(RequiredFieldBox.EnmValidationType),
                                                                                         typeof(RequiredFieldBox),
                                                                                         new FrameworkPropertyMetadata(RequiredFieldBox.EnmValidationType.FieldNotEmpty));
    public EnmValidationType Type
    {
        get { return (EnmValidationType) GetValue(TypeProperty); }
        set { SetValue(TypeProperty, value);}
    }
    private static void MessageChanaged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        RequiredFieldBox sh = (RequiredFieldBox)d;
        if (sh.Msg != (string)e.OldValue)
            sh.Msg = (string)e.NewValue;
    }
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",                               //Property name
    typeof( object ),                           //Property type
    typeof( RequiredFieldBox ));

    public string Msg
    {
        get { return (string)GetValue(MsgProperty); }
        set { SetValue(MsgProperty, value); }
    }

    public object Text
    {
        get { return GetValue(TextProperty);}
        set { SetValue(TextProperty, value); }
    }
}
验证规则类

public class RequiredFieldBox : Control
{

    static RequiredFieldBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(RequiredFieldBox), new FrameworkPropertyMetadata(typeof(RequiredFieldBox)));
    }
    public static readonly DependencyProperty MsgProperty = DependencyProperty.Register(
     "Msg",
     typeof(string),
     typeof(RequiredFieldBox),
     new FrameworkPropertyMetadata(null)
   );
    public enum EnmValidationType
    {
        FieldNotEmpty,
        FieldNumeric,
        FieldIPAddress
    }
    public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type",
                                                                                         typeof(RequiredFieldBox.EnmValidationType),
                                                                                         typeof(RequiredFieldBox),
                                                                                         new FrameworkPropertyMetadata(RequiredFieldBox.EnmValidationType.FieldNotEmpty));
    public EnmValidationType Type
    {
        get { return (EnmValidationType) GetValue(TypeProperty); }
        set { SetValue(TypeProperty, value);}
    }
    private static void MessageChanaged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        RequiredFieldBox sh = (RequiredFieldBox)d;
        if (sh.Msg != (string)e.OldValue)
            sh.Msg = (string)e.NewValue;
    }
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",                               //Property name
    typeof( object ),                           //Property type
    typeof( RequiredFieldBox ));

    public string Msg
    {
        get { return (string)GetValue(MsgProperty); }
        set { SetValue(MsgProperty, value); }
    }

    public object Text
    {
        get { return GetValue(TextProperty);}
        set { SetValue(TextProperty, value); }
    }
}
公共类RequiredFieldRule:ValidationRule {


在验证规则中,没有上下文或树连接,因为模板绑定大致相当于
相对资源
绑定,它将不起作用。您可能运气不好

通常,唯一有效的方法是与
StaticResource
x:Static
结合使用,因为您不能通过名称引用模板化的父级,您可以通过另一个控件对其进行隧道,例如:

<TextBox x:Name="RequiredFieldBox"
         Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}">
    <TextBox.Resources>
        <rule:RequiredFieldRule x:Key="rule">
            <rule:RequiredFieldRule.Params>
                <rule:ValidationParams 
                    Message="{Binding Tag.Msg, Source={x:Reference RequiredFieldBox}}"
                    ValidationType="{Binding Tag.Type, Source={x:Reference RequiredFieldBox}}"/>
            </rule:RequiredFieldRule.Params>
        </rule:RequiredFieldRule>
    </TextBox.Resources>
    <!-- ... --->
         <Binding.ValidationRules>
             <StaticResource ResourceKey="rule"/>
         </Binding.ValidationRules>

只是想一想为什么ValidationType可以工作?而消息只是不工作,这个绑定会引发一个异常。不知道为什么,但无法创建Tag.Type依赖项Property@NividDholakia:
ValidationType
使用了
TemplateBinding
?这很有趣,您可能想查看任何输出,也许吧模板绑定确实可以工作,但还有一些问题。我发布的代码中没有绑定错误。所有内容都是正确的。如果您需要,可以从添加的链接下载示例项目的副本。很抱歉,该链接现在是最新的WpfCustomValidatorProject@NividDholakia:ValidationType目前也不工作正如我所看到的,它总是默认值…我添加了另一个方法来隧道所需的属性。
<TextBox x:Name="RequiredFieldBox"
         Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}">
    <TextBox.Resources>
        <rule:RequiredFieldRule x:Key="rule">
            <rule:RequiredFieldRule.Params>
                <rule:ValidationParams 
                    Message="{Binding Tag.Msg, Source={x:Reference RequiredFieldBox}}"
                    ValidationType="{Binding Tag.Type, Source={x:Reference RequiredFieldBox}}"/>
            </rule:RequiredFieldRule.Params>
        </rule:RequiredFieldRule>
    </TextBox.Resources>
    <!-- ... --->
         <Binding.ValidationRules>
             <StaticResource ResourceKey="rule"/>
         </Binding.ValidationRules>
<StackPanel Orientation="Vertical">
    <StackPanel.Resources>
        <FrameworkElement x:Key="Tunnel"
                Tag="{Binding RelativeSource={RelativeSource AncestorType=local:RequiredFieldBox}}" />
    </StackPanel.Resources>
    <StaticResource ResourceKey="Tunnel" />
    <TextBox x:Name="RequiredFieldBox">
        <TextBox.Text>
            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Text">
                <Binding.ValidationRules>
                    <rule:RequiredFieldRule>
                        <rule:RequiredFieldRule.Params>
                            <rule:ValidationParams
                                    Message="{Binding Tag.Msg, Source={StaticResource Tunnel}}"
                                    ValidationType="{Binding Tag.Type, Source={StaticResource Tunnel}}" />
                        </rule:RequiredFieldRule.Params>
                    </rule:RequiredFieldRule>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>