WPF MVVM TextBox更新未发生

时间:2015-03-26 04:04:21

标签: wpf mvvm

我是WPF MVVM的新手;所以,这是一个非常简单的测试程序,暴露了TextBox更新问题。参考下面的代码,检查CheckBox(View1.xml中的Name =“view1TextBox1”)调用ViewModel1BoolField1(ViewModel1.cs)属性,其中调用RunTest(Model1.cs)。然后RunTest返回一个字符串(ViewModel1.cs)。然后将此字符串分配给ViewModel1StringField1属性。这是问题发生的地方,因为TextBox view1TextBox1(View.xml)未使用测试字符串“Testing 123”进行更新。我不确定我是否正确使用“OnPropertyChanged”(ViewModelBase.cs)或view1TextBox1“UpdateSourceTrigger = PropertyChanged”(View1.xml)来更新TextBox。任何见解都会很棒。谢谢!

<UserControl x:Class="WpfMVVMExample1.View.View1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <StackPanel Orientation="Vertical">
            <TextBox Width="100" Height="100" Name="view1TextBox1" TextWrapping="Wrap" AcceptsReturn="True" Text="{Binding ViewModel1StringField1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <CheckBox Name="view1CheckBox1" IsChecked="{Binding ViewModel1BoolField1}"/>
        </StackPanel>
    </UserControl>

namespace WpfMVVMExample1.ViewModel
{
    public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

        public void Dispose()
        {
            this.OnDispose();
        }

        protected virtual void OnDispose()
        {
        }
    }
}   

namespace WpfMVVMExample1.ViewModel
{
    class ViewModel1 : ViewModelBase
    {
        #region Fields
        Model1 _model1;
        #endregion

        #region Constructors
        public ViewModel1()
        {
            _model1 = new Model1 { Model1StringField1 = "Field1" };
        }
        #endregion

        #region Properties

        public Model1 Model1
        {
            set
            {
                _model1 = value;
            }
            get
            {
                return _model1;
            }
        }

        public string ViewModel1StringField1
        {
            get
            {
                return Model1.Model1StringField1;
            }

            set
            {
                Model1.Model1StringField1 = value;
                OnPropertyChanged(ViewModel1StringField1);
            }
        }

        public bool ViewModel1BoolField1
        {
            get
            {
                return Model1.Model1BoolField1;
            }
            set
            {
                Model1.Model1BoolField1 = value;
                if (value)
                {
                    ViewModel1StringField1 = Model1.RunTest();
                }
            }
        }         
        #endregion
    }
}

namespace WpfMVVMExample1.Model
{
    class Model1
    {
        #region Fields
        string _model1StringField1;
        bool _model1BoolField1;
        #endregion

        #region Properties
        public string Model1StringField1
        {
            get 
            { 
                return _model1StringField1; 
            }
            set
            {
                _model1StringField1 = value;
            }
        }

        public bool Model1BoolField1
        {
            get
            {
                return _model1BoolField1;
            }
            set
            {
                _model1BoolField1 = value;
            }
        }
        #endregion

        #region Functions
        public string RunTest()
        {
            return "Testing 123";
        }
        #endregion
    }
}

2 个答案:

答案 0 :(得分:2)

当您调用属性更改时,您应该传入已更改的属性名称。目前您正在传递该属性的值。

OnPropertyChanged(ViewModel1StringField1); }

应该是

OnPropertyChanged("ViewModel1StringField1"); }

答案 1 :(得分:1)

如果查看ViewModelBase课程,您会看到此方法签名:

protected virtual void OnPropertyChanged(string propertyName)

此方法的参数是已更改的属性的名称。但是,当您在ViewModel1StringField1 setter中调用它时,请执行以下操作:

OnPropertyChanged(ViewModel1StringField1);

您将传递其值,而不是属性名称,该值可以是用户放入的任何内容。相反,您要执行此操作:

OnPropertyChanged("ViewModel1StringField1");

缺点是属性名称现在是字符串,当您更改属性的名称时,编译器不会检查它。所以请注意(有其他方法可以做到这一点)。