【问题标题】:PropertyChanged remains null even if the property has been changed即使属性已更改,PropertyChanged 仍为 null
【发布时间】:2020-04-04 14:30:13
【问题描述】:

我为此苦苦挣扎了一段时间,但我无法弄清楚。我有一个按钮和一个文本框。文本框链接到一个名为:MessageDisplay 的属性。我希望能够访问此属性并在多个位置更新文本框。可悲的是,PropertyChanged 为空。奇怪的是,如果我将 MessageDisplayModel 类复制/粘贴到 *MessageViewModel * 类中,它可以工作......

这是我的代码: XAML 文件:

<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

主窗口文件

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

我使用 UpdateTextBox(string) 方法更新 MessageDisplay 属性。我在单击按钮时调用此方法。 调试时属性会更新,但是当通知 UI 属性已更改时,PropertyChangedEventHandler PropertyChanged 的值为 null ...但是如果我在文本框,PropertyChangedEventHandler PropertyChanged 被更改并且不再为空。我想要的只是能够随时随地更改文本框的属性。 谢谢你

【问题讨论】:

    标签: wpf mvvm data-binding


    【解决方案1】:

    您正在使用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>
    

    【讨论】:

    • 感谢您的回复@BionicCode,您帮了大忙。另外,感谢有关“DisplayTextCommand”的评论,确实设置错误。
    猜你喜欢
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2015-07-07
    • 2020-11-16
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多