Привязка OneWay перестает работать после ручного обновления целевого объекта

У меня есть такой код привязки WPF:

TestModel source = new TestModel();
TestModel target = new TestModel();

Bind(source, target, BindingMode.OneWay);

source.Attribute = "1";
AssertAreEqual(target.Attribute, "1");

target.Attribute = "foo";

source.Attribute = "2";
AssertAreEqual(target.Attribute, "2");

Второе утверждение неверно! Мне это кажется странным.

Кроме того, я попробовал OneWayToSource вместо OneWay, и все работает, как ожидалось.

Bind(source, target, BindingMode.OneWayToSource);

target.Attribute = "1";
AssertAreEqual(source.Attribute, "1");

source.Attribute = "foo";

target.Attribute = "2";
AssertAreEqual(source.Attribute, "2");

Другие детали:

void Bind(TestModel source, TestModel target, BindingMode mode)
{
    Binding binding = new Binding();
    binding.Source = source;
    binding.Path = new PropertyPath(TestModel.AttributeProperty);
    binding.Mode = mode;
    BindingOperations.SetBinding(target, TestModel.AttributeProperty, binding);
}

class TestModel : DependencyObject
{
    public static readonly DependencyProperty AttributeProperty =
        DependencyProperty.Register("Attribute", typeof(string), typeof(TestModel), new PropertyMetadata(null));

    public string Attribute
    {
        get { return (string)GetValue(AttributeProperty); }
        set { SetValue(AttributeProperty, value); }
    }
}

Что не так с моим кодом?


person alex2k8    schedule 28.02.2009    source источник


Ответы (4)


Установка target.Attribute = "foo"; очистил переплет.

MSDN:

Мало того, что динамические ресурсы и привязки работают с тем же приоритетом, что и локальное значение, они действительно являются локальным значением, но со значением, которое является отложенным. Одним из следствий этого является то, что если у вас есть динамический ресурс или привязка для значения свойства, любое локальное значение, которое вы устанавливаете впоследствии, полностью заменяет динамическую привязку или привязку. Даже если вы вызовете ClearValue, чтобы очистить локально установленное значение, динамический ресурс или привязка не будут восстановлены. Фактически, если вы вызываете ClearValue для свойства, имеющего динамический ресурс или привязку (без «буквального» локального значения), они также очищаются вызовом ClearValue.

person alex2k8    schedule 01.03.2009

Не эксперт по связыванию, но я считаю, что вы сталкиваетесь с проблемами приоритета свойств зависимостей WPF. Вероятно, что установка значения напрямую имеет приоритет над значением привязки. Вот почему он отменяет привязку.

Вот полный список свойств зависимостей: http://msdn.microsoft.com/en-us/library/ms743230.aspx

person JaredPar    schedule 28.02.2009
comment
Это делает разумным, что значение, установленное через стиль, будет переопределять значение шаблона, а локальное значение переопределит значение стиля и т. Д. Но у меня нет ничего об этом. Не уверен, что это объясняет проблему ... В любом случае спасибо. - person alex2k8; 28.02.2009
comment
Кроме того, это не объясняет разницу между OneWay и OneWayToSource. - person alex2k8; 28.02.2009

Пример: TextProperty является свойством зависимости TextBox. Вызов их в коде должен быть:

TextBox1.TextProperty = "значение";

Свойства WPF можно установить двумя способами: путем вызова метода DependencyObject.SetValue (например, instance.SetValue (TextProperty, «некоторый текст»)) или с помощью CLR Wrapper (например, instance.Text = «некоторый текст»).

TextBox.TextProperty - это статический объект DependencyProperty, поэтому вы не можете присвоить строковое значение ссылочному типу.

person Vlad    schedule 03.08.2009

Если вы установите режим привязки на OneWay, это означает, что привязка работает только одним способом: цель обновляется при изменении источника.

Но целью должно быть свойство зависимости, а имеющийся у вас код - это свойство CLR .NET. Вы должны установить значение в целевом объекте, используя зарегистрированное имя свойства зависимости, а не просто обычное имя свойства .NET. Ответ Джареда совершенно правильный, это может вызвать путаницу при разрешении конфликта между свойством зависимости WPF и обычным свойством .NET CLR.

Если вы следуете соглашению, свойство зависимости должно быть в форме «имя свойства» + свойство.

Пример: TextProperty является свойством зависимости TextBox. Вызов их в коде должен быть:

TextBox1.TextProperty="value";

Для получения дополнительной информации о настройке источника привязки:

http://msdn.microsoft.com/en-us/library/ms743643.aspx

person Eriawan Kusumawardhono    schedule 28.02.2009
comment
Я добавил TestModel, чтобы избежать путаницы ... Также, пожалуйста, посмотрите мой метод привязки - я использую свойство зависимости WPF. Я использую оболочку свойств CLR только для установки значения свойства WPF ... Кроме того, TextBox1.TextProperty = value; Что ты имеешь в виду? Экземпляр TextBox имеет только свойство Text. - person alex2k8; 28.02.2009