PropertyChanged остается нулевым, даже если свойство было изменено - PullRequest
0 голосов
/ 04 апреля 2020

Я борюсь с этим некоторое время, и я не могу понять это. У меня есть кнопка и текстовое поле. TextBox связан со свойством с именем: MessageDisplay. Я хочу иметь доступ к этому свойству и обновлять textBox в нескольких местах. К сожалению, PropertyChanged является нулевым. Странно то, что если я скопирую / вставлю класс MessageDisplayModel в класс * MessageViewModel *, он будет работать ...

вот мой код: XAMLfile:

<Grid>
    <Button Command="{Binding DisplayTextCommand}" Name="DisplayTextCommand"  Margin="53,72,544.6,286" Width="Auto">Push</Button>
    <TextBox Name="MessageDisplay" Text="{Binding MessageDisplay, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  />
</Grid>

Файл MessageDisplayModel

public class MessageDisplayModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _message;
        public string MessageDisplay
        {
            get { return _message; }
            set
            {
                this._message = value;
                this.OnPropertyChanged("MessageDisplay");
            }
        }

        public void UpdateTextBox(string output)
        {
            MessageDisplay = output;
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {

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

Файл MessageViewModel:

public class MessageViewModel
    {
        private ICommand _testCommand;
        public MessageDisplayModel MessageDisplaySmt = new MessageDisplayModel();

        public ICommand DisplayTextCommand
        {
            get
            {
                return new DelegateCommand(DisplayMessage);
            }
            set
            {
                if (_testCommand == value) return;
                _testCommand = value;
            }
        }

        public void DisplayMessage()
        {
            MessageDisplaySmt.UpdateTextBox("Successfuly downloaded");
        }

    }//class

Файл MainWindow

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MessageDisplay.DataContext = new MessageDisplayModel();
            DisplayTextCommand.DataContext = new MessageViewModel();
        }
    }//class

Я обновляю свойство MessageDisplay с помощью метода UpdateTextBox (строка) , Я вызываю этот метод по нажатию кнопки. При отладке свойство обновляется, но когда приходит время уведомить пользовательский интерфейс об изменении свойства, PropertyChangedEventHandler PropertyChanged имеет значение null ... Но если я что-то напишу в textBox, PropertyChangedEventHandler PropertyChanged изменяется и больше не является нулевым. Все, что я хочу, - это иметь возможность изменять свойство textBox, когда захочу и откуда угодно. Спасибо

1 Ответ

0 голосов
/ 05 апреля 2020

Вы используете два разных экземпляра MessageDisplayModel. Вы должны использовать общий экземпляр.

Также DisplayTextCommand реализован "неправильно". Метод set является избыточным, поскольку свойство get всегда возвращает новый экземпляр ICommand.

MessageViewModel.cs

public class MessageViewModel
{
  pulic MessageViewModel()
  {
  }

  pulic MessageViewModel(MessageDisplayViewModel messageDisplayViewModel)
  {
    this.MessageDisplaySmt = messageDisplayViewModel;
  }

  public void DisplayMessage()
  {
    this.MessageDisplaySmt.UpdateTextBox("Successfuly downloaded");
  }

  public MessageDisplayViewModel MessageDisplaySmt { get; set; }

  public ICommand DisplayTextCommand { get => new DelegateCommand(DisplayMessage); }
}

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    // Alternatively use XAML to set the DataContext (see MainWindow.xaml). Would require a parameterless constructor.
    this.DataContext = new MessageViewModel(new MessageDisplayViewModel());
  }
}

MainWindow.xaml

<Window>

  <!-- 
    Alternative DataContext declaration using XAML instead of C#. 
    Requires a parameterless constructor for both view model objects. 
  -->
  <Window.DataContext>
    <MessageViewModel>
      <MessageViewModel.MessageDisplaySmt>
        <MessageDisplayViewModel />
      </MessageViewModel.MessageDisplaySmt>
    </MessageViewModel>
  </Window.DataContext>

  <StackPanel>
    <Button Command="{Binding DisplayTextCommand}" 
            Content="Push" />
    <TextBox Text="{Binding MessageDisplaySmt.MessageDisplay}" />
  </StackPanel>
</Window>
...