首页 文章

从xaml中清除dependencyProperty值

提问于
浏览
4

我有一个控件,它具有属性的默认值 . 当控件首次设置其dataContext时,它会自动分配此属性 .

现在在xaml中,我希望它可以UNset这个属性 . 我已经尝试将它设置为x:只是空字符串的空,但后来我得到一个错误,因为该属性没有转换器 . 在我希望禁用该功能的极少数情况下,如何从xaml中取消分配此属性?

最初设置的代码:

void OmniBox_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if( e.NewValue is BindingObjectBaseExtended )
    {
        BindingObjectBaseExtended value = (BindingObjectBaseExtended)e.NewValue;
        this.SetBinding(OmniBox.ContextValidationMessagesProperty, new Binding() { Source = value, Path = new PropertyPath("ValidationMessages") });
    }
}

xaml我要取消设置属性 .

<Style TargetType="ui:OmniBox">
    <Setter Property="ContextValidationMessages" Value="" />
</Style>

请注意,如果我在数据上下文更改时没有自动设置绑定,那么默认情况下没有验证消息,我必须在xaml中执行以下操作来设置它们:

<Style TargetType="ui:OmniBox">
    <Setter Property="ContextValidationMessages" Value="ValidationMessages" />
</Style>

我正在尝试做的是使上面的绑定成为我的自定义OmniBox控件的默认值,并允许用户取消设置或将其更改为其他内容 .

4 回答

  • 1

    就个人而言,我会创建一个单独的依赖属性,例如 bool AutoBindValidation 并使其默认为true . 如果它是假的,那么你可能根本不想公开曝光 ContextValidationMessages .

    如果你真的想按照你发布的方式去做,我不确定为什么将它设置为 {x:Null} 会导致错误(除非属性类型不可为空) . 但是这种方法会有问题,因为 DataContextChanged 将在解析XAML之后发生 . 因此用户可以将其设置为 {x:Null} ,但随后DataContext将更改,您的代码将设置默认绑定并践踏用户's value. You could set up the binding in the control'的contstructor,但是如果DataContext没有 ValidationMessages 属性,则您的控件将吐出绑定错误 .

  • 4
  • 1

    这可能是不可能的,我最好的选择是:

    <Setter Property="ContextValidationMessages"
            Value="{x:Static DependencyProperty.UnsetValue}" />
    

    但那抛出 "Cannot unset setter value" . 所以你最好反转你的逻辑或保持 property 不设置另一种方式 .

  • 2

    我认为在xaml本身中没有任何支持的方法可以做到这一点 . 在您的代码中,您在 ContextValidationMessagesProperty 上设置了本地值 . 您包含的样式设置器具有较低的dependency property precedence,即使它们被评估,它们也会根据指定的值设置一个值 - 不清楚它 . 也许不是在代码中设置绑定,而是可以在OmniBox的默认样式中设置Setter来设置该属性 - 例如

    <Setter Property="ContextValidationMessages" Value="{Binding ValidationMessages}" />
    

    如果必须有条件地设置Binding,则可以创建一个自定义IValueConverter来检查指定的类型(作为参数传递) . 例如

    public class IsAssignableFromConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Type typeParameter = parameter as Type;
    
            if (typeParameter == null)
                return DependencyProperty.UnsetValue;
    
            return value != null && typeParameter.IsAssignableFrom(value.GetType());
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }
    

    然后你可以像这样使用它:

    <local:IsAssignableFromConverter x:Key="isAssignableConverter" />
        <Style TargetType="ui:OmniBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Converter={StaticResource isAssignableConverter}, ConverterParameter={x:Type ui:BindingObjectBaseExtended}}" Value="True">
                    <Setter Property="ContextValidationMessages" Value="{Binding ValidationMessages}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    

    如果您不希望应用此属性,可以将OmniBox的该实例的样式设置为新样式,并确保set the OverridesDefaultStyle property to true .

    我想另一种选择是创建另一个依赖属性,它将在ContextValidationMessages属性上调用ClearValue,但这似乎可能是一个维护问题 .

相关问题