首页 > 解决方案 > 即使属性已更改,PropertyChanged 仍为 null

问题描述

我为此苦苦挣扎了一段时间,但我无法弄清楚。我有一个按钮和一个文本框。文本框链接到一个名为:MessageDisplay 的属性。我希望能够访问此属性并在多个位置更新文本框。可悲的是,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>

消息显示模型文件

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

消息视图模型文件:

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

主窗口文件

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

我使用 UpdateTextBox(string) 方法更新 MessageDisplay 属性。我在单击按钮时调用此方法。调试时属性会更新,但到了通知 UI 属性已更改时, PropertyChangedEventHandler PropertyChanged​​值为 null ... 我想要的只是能够随时随地更改文本框的属性。谢谢

标签: wpfmvvmdata-binding

解决方案


您正在使用两个不同的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); }
}

主窗口.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());
  }
}

主窗口.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>

推荐阅读