Двусторонняя привязка в WPF

Я не могу заставить работать двустороннюю привязку в WPF.

У меня есть строковое свойство в главном окне моего приложения, которое привязано к TextBox (я установил режим «TwoWay»).

Единственный раз, когда значение TextBox будет обновляться, - это когда окно инициализируется.

Когда я набираю текст в TextBox, значение базовых свойств строки не изменяется.

Когда значение свойства строки изменяется внешним источником (например, событие Click, которое просто сбрасывает значение TextBox), изменение не распространяется до TextBox.

Какие шаги я должен выполнить, чтобы двусторонняя привязка работала должным образом даже в этом почти тривиальном примере?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
0
56 709
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Возможно, нам понадобится увидеть код. Вызывает ли ваше строковое свойство событие PropertyChanged? Или (что еще лучше) реализовано как DependencyProperty? В противном случае связанный TextBox не узнает, когда значение изменится.

Что касается ввода текста в TextBox и отсутствия изменения значения свойства, это может быть связано с тем, что ваш TextBox не теряет фокус. По умолчанию связанные TextBox не записывают свои значения обратно в исходное свойство, пока фокус не покинет элемент управления. Попробуйте выйти из него и посмотреть, изменится ли значение свойства.

Ответ принят как подходящий

Скорее всего, вы пытаетесь выполнить привязку к свойству CLR .net, а не к WPF dependencyProperty (которое предоставляет уведомление об изменении в дополнение к некоторым другим вещам). Для обычного свойства CLR вам необходимо реализовать INotifyPropertyChanged и принудительно обновить текстовое поле в обработчике событий для PropertyChanged.

  • Итак, сделайте так, чтобы ваш объект со свойством реализовал этот интерфейс, вызовите событие в установщике свойств. (Итак, теперь у нас есть уведомление об изменении свойства)
  • Убедитесь, что объект установлен как свойство DataContext элемента / элемента управления пользовательского интерфейса.

Это тоже сбило меня с толку, когда я начал изучать привязку данных WPF.

Обновлять:Что ж, ОП, это было бы пустой тратой времени, если бы я лаял не на то дерево ... в любом случае теперь, когда тебе пришлось немного копать ... ты запомнишь это надолго. Вот фрагмент кода, чтобы завершить этот ответ. Также обнаружено, что обновление текстового поля происходит автоматически, как только я выхожу на вкладку. Вам нужно только вручную подписаться на событие и обновить пользовательский интерфейс, если ваш объект datacontext не тот, который реализует INotifyPropertyChanged.

MyWindow.xaml

<Window x:Class = "DataBinding.MyWindow" ...
    Title = "MyWindow" Height = "300" Width = "300">
    <StackPanel x:Name = "TopLevelContainer">
        <TextBox x:Name = "txtValue"  Background = "AliceBlue" Text = "{Binding Path=MyDotNetProperty}" />
        <TextBlock TextWrapping = "Wrap">We're twin blue boxes bound to the same property.</TextBlock>
        <TextBox x:Name = "txtValue2"  Background = "AliceBlue" Text = "{Binding Path=MyDotNetProperty}" />
    </StackPanel>
</Window>

MyWindow.xaml.cs

public partial class MyWindow : Window, INotifyPropertyChanged
{
    public MyWindow()
    {
        InitializeComponent();
        this.MyDotNetProperty = "Go ahead. Change my value.";
        TopLevelContainer.DataContext = this;
    }

    private string m_sValue;
    public string MyDotNetProperty
    {
        get { return m_sValue; }
        set
        {
            m_sValue = value;
            if (null != this.PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("MyDotNetProperty"));
            }
        }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
}

Это помогло мне, так что +1, но мне также пришлось включить UpdateSourceTrigger=PropertyChanged в мое определение {Binding} в xaml, чтобы оно заработало.

Joel Brown 24.10.2012 18:05

Я чувствую необходимость добавить немного точности:

«Двусторонняя» привязка данных - это больше, чем «односторонняя» привязка данных.

«Односторонняя» привязка данных - это привязка источника к свойству зависимости. Источник должен реализовать INotifyProertyChanged, чтобы получить распространение изменения от источника к цели.

Чтобы получить "2 пути", чтобы получить распространение от цели к источнику, это зависит от режима привязки, который вы установили в привязке. Если вы не установите для привязки какой-либо BindingMode, будет использоваться режим привязки по умолчанию, и этот режим по умолчанию является характеристикой вашего целевого свойства зависимости.

Пример:

Текстовое поле, привязанное к строковому свойству, которое называется «MyTextProperty». В коде вы привязываете Textbox.Text DependencyProperty к «MyTextProperty» на объекте «MyObject».

-> «односторонняя» привязка: установщик «My TextProperty» должен вызывать событие «Property Changed», а «MyObject» должен реализовывать INotifyPropertyChanged.

-> «Двухсторонняя привязка данных»: в дополнение к тому, что необходимо для «Одностороннего», для параметра bindingMode должно быть установлено значение «2 способа». В этом особом случае Text DependencyProperty для Textbox действительно имеет «2 способа» в качестве режима по умолчанию, так что делать больше нечего!

Другие вопросы по теме