Очистить значение dependencyProperty из xaml - PullRequest
4 голосов
/ 01 ноября 2011

У меня есть элемент управления, который имеет значение по умолчанию для свойства.Когда элемент управления сначала получает свой набор dataContext, он автоматически назначает это свойство.

Теперь в xaml я хочу, чтобы было возможно отменить это свойство.Я попытался установить для x: Null только пустую строку, но затем я получаю сообщение об ошибке, потому что для свойства нет конвертера.Как мне просто отменить назначение этого свойства в 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 ]

4 голосов
/ 09 сентября 2014

DependencyProperty.UnsetValue нельзя использовать в XAML.

http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.unsetvalue(v=vs.90).ASPX

2 голосов
/ 01 ноября 2011

Лично я хотел бы создать отдельное свойство зависимостей, такое как bool AutoBindValidation, и установить для него значение по умолчанию true. Если это ложь, не делайте ничего, когда DataContext изменяется. Это немного больше самодокументирования. В зависимости от того, что именно вы пытаетесь сделать, вы можете вообще не хотеть публично выставлять ContextValidationMessages.

Если вы действительно хотите сделать это так, как вы разместили, я не уверен, почему установка его на {x:Null} может привести к ошибке (если тип свойства не имеет значения null). Но у этого подхода будут проблемы, потому что DataContextChanged произойдет после разбора XAML. Таким образом, пользователь может установить его на {x:Null}, но затем DataContext изменится, и ваш код установит привязку по умолчанию и растопчет значение пользователя. Вы можете установить привязку в contstructor элемента управления, но если DataContext не имеет свойства ValidationMessages, ваш элемент управления будет выплевывать ошибки привязки.

1 голос
/ 01 ноября 2011

Я не думаю, что есть какой-либо поддерживаемый способ сделать это в самом xaml.В своем коде вы устанавливаете локальное значение для ContextValidationMessagesProperty .Установленные вами сеттеры стилей будут иметь более низкий приоритет свойства зависимостей , и даже если они будут оценены, они установят значение на основе указанного значения - не очистить его.Возможно, вместо того, чтобы устанавливать привязку в коде, вы можете использовать Setter в своем стиле по умолчанию для OmniBox, который устанавливает это свойство - например,

<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 в новом стиле и убедитесь, что установите для свойства OverridesDefaultStyle значение true .

Я предполагаю, что другой вариант заключается в создании другого свойства зависимости, которое будет вызывать ClearValue для свойства ContextValidationMessages, но это кажетсякак будто это может быть проблема с обслуживанием.

1 голос
/ 01 ноября 2011

Это может быть невозможно, моя лучшая ставка была такой:

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

Но это бросает "Cannot unset setter value".Так что вам лучше изменить свою логику или оставить свойство неустановленным другим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...