我是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
}
}
答案 0 :(得分:2)
当您调用属性更改时,您应该传入已更改的属性名称。目前您正在传递该属性的值。
OnPropertyChanged(ViewModel1StringField1); }
应该是
OnPropertyChanged("ViewModel1StringField1"); }
答案 1 :(得分:1)
如果查看ViewModelBase
课程,您会看到此方法签名:
protected virtual void OnPropertyChanged(string propertyName)
此方法的参数是已更改的属性的名称。但是,当您在ViewModel1StringField1
setter中调用它时,请执行以下操作:
OnPropertyChanged(ViewModel1StringField1);
您将传递其值,而不是属性名称,该值可以是用户放入的任何内容。相反,您要执行此操作:
OnPropertyChanged("ViewModel1StringField1");
缺点是属性名称现在是字符串,当您更改属性的名称时,编译器不会检查它。所以请注意(有其他方法可以做到这一点)。