it-roy-ru.com

Привязка WPF не обновляет представление

У меня есть текстовый блок:

<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText}">
            ... Status ...
</TextBlock>

отделенный код:

public StatusPage()
{
    InitializeComponent();
    this.DataContext = new StatusPageViewModel(this);
}

и в viewModel:

private string _statusText;
/// <summary>
/// Status text
/// </summary>
public string StatusText
{
    get { return _statusText; }
    set { _statusText = value; }
}

и в функции в viewModel:

string statusText = Status.GetStatusText();
this.StatusText = statusText;

GetStatusText() возвращает строку типа «Работа выполнена» и т. д. Значения этих функций передаются в this.StatusText, но текстовое свойство TextBlock не изменяется и по-прежнему отображает заполнитель «... Status ...»

Мне известны такие вопросы -> CLICK <--- но после прочтения я все еще не могу найти решение

@Обновление

После ваших предложений я обновил свой код, и теперь у меня есть это:

public string StatusText
{
    get 
    {
        return _statusText;
    }
    set 
    {
        _statusText = value; 
        RaisePropertyChanged("StatusText");
    }
}

и объявление viewModel:

 public class StatusPageViewModel : ObservableObject, INavigable

где:

Класс ObservableObject:

public abstract class ObservableObject : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    /// <summary>
    /// Raises the PropertyChange event for the property specified
    /// </summary>
    /// <param name="propertyName">Property name to update. Is case-sensitive.</param>
    public virtual void RaisePropertyChanged(string propertyName)
    {
        OnPropertyChanged(propertyName);
    }

    /// <summary>
    /// Raised when a property on this object has a new value.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

    #endregion // INotifyPropertyChanged Members
}

Но его все еще не работает

16
szpic

Вам необходимо реализовать INotifyPropertyChanged в вашем ViewModel, чтобы уведомить View об изменении свойства.

Вот ссылка на страницу MSDN для этого: System.ComponentModel.INotifyPropertyChanged

Самая важная вещь, на которую стоит обратить внимание, это то, что вы должны вызвать событие PropertyChanged в вашем установщике свойств.

22
toadflakz

Добавьте режим связывания двумя способами, потому что по умолчанию режим связывания Textblock является односторонним

<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            ... Status ...
</TextBlock>

а также, конечно, вам необходимо реализовать INotifyPropertyChanged для этой цели, обратитесь к этой ссылке как это реализовать.

10
Mayur Dhingra

При работе с DataModels вы должны быть уверены, что модель завершена при первоначальной загрузке. Поэтому, если вы сделаете это: this.DataContext = mainViewModel и некоторые части вашего mainViewModel НЕ загружены (= ноль), то вы не сможете их связать. Например, у меня есть модель в этой модели объектной программы. Я привязываю к тексту TextBlock к Model.Program.Name. Объект Program не подключается при начальной загрузке, поэтому вам придется выполнить повторную привязку к загруженному объекту после этого, поскольку в противном случае никакие уведомления не могут быть отправлены.

3
Herman Van Der Blom

Ваша модель представления должна реализовывать INotifyPropertyChanged, и вам нужно повышать ее каждый раз, когда изменяется одно из ваших свойств (например, в установщике). 

Без этого WPF не может знать, что свойство изменилось.

2
GazTheDestroyer

У меня была эта проблема, и вот что я делаю не так ...

Примечание: я правильно закодировал INotifyPropertyChanged.


На мой взгляд, я имел

<SomeView.DataContext>
    <SomeViewModel/>
<SomeView.DataContext/>

... и это вызывает конструктор VM (создание экземпляра для указания на/для привязки).

В другом классе (в коде ViewModel для главного окна моей программы) я также создавал экземпляры ViewModel, т.е.

private SomeAstractBaseViewModel someViewModel = new SomeViewModel();
private SomeAstractBaseViewModel someOtherViewModel = new SomeOtherViewModel(); 

Они оба унаследованы от суперкласса, и я переключался назад и вперед между экземплярами, показывающими разные виды в разделе главного окна - согласно моему намерению.

Как все это подключено - другой вопрос, но когда я удаляю проблемныйxaml(вверху этого ответа), который ранее создавал экземпляр другого «неиспользуемого» экземпляра ViewModel, представление обновлялось в соответствии сINotifyPropertyChangedмеханизмы.

0
JohnG79