Двусторонняя привязка в WPF - PullRequest
29 голосов
/ 26 ноября 2008

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

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

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

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

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

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

Ответы [ 3 ]

59 голосов
/ 26 ноября 2008

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

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

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

Обновление: Что ж, OP, было бы пустой тратой времени, если бы я лаял не то дерево ... в любом случае сейчас, так как вам пришлось немного покопаться ... вы будете помнить это долго. Вот фрагмент кода, чтобы завершить этот ответ. Также обнаружено, что обновление текстового поля происходит автоматически, как только я выхожу из системы. Вам нужно только вручную подписаться на событие и обновить пользовательский интерфейс, если ваш объект 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
}
5 голосов
/ 23 сентября 2011

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

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

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

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

Пример:

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

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

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

3 голосов
/ 26 ноября 2008

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

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

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