MVVM WPF:为啥在运行应用程序时更新文本框中的文本后模型中的属性始终为空?
Posted
技术标签:
【中文标题】MVVM WPF:为啥在运行应用程序时更新文本框中的文本后模型中的属性始终为空?【英文标题】:MVVM WPF: Why is the property in the Model always null even after updating the text in textbox while running the application?MVVM WPF:为什么在运行应用程序时更新文本框中的文本后模型中的属性始终为空? 【发布时间】:2021-10-30 06:34:39 【问题描述】:我放弃了 MVP 模式,尝试了 MVVM 和 WPF。到目前为止,我设法通过单击不同的按钮来导航显示不同用户控件的菜单。 DataBinding 和 Commands 在导航中运行良好,但是在 DataBinding 文本框时遇到了问题。
该属性总是得到 null 值,我不知道为什么。我添加了一个命令,以便在单击按钮时从文本框中获取用户 ID,并显示一个包含用户 ID 的消息框,以便在我尝试其他任何操作之前使其变得简单。
MessageBox 显示,但它是空的。我在 UsersModel.cs 中添加了一个 Task.Run,因此我可以查看字符串是否在 propertychange 上更新但值为 null。
我正在使用 ObservableObject 的类来通知 OnPropertyChanged。还有一个继承自 ICommand 的 RelayCommand 类。两者似乎都按预期工作,但仅在单击按钮以显示不同的用户控件并关闭应用程序时。下面是来自 View、Model 和 ViewModel 的示例代码。我错过了什么?
RegisterMenu.xaml
<TextBox x:Name="RegTextUserID" Margin="163,66,148,112"
Style="StaticResource ResourceKey=UserBox"
Text="Binding UserID, UpdateSourceTrigger=PropertyChanged">
<TextBox.DataContext>
<models:UsersModel/>
</TextBox.DataContext>
</TextBox>
<Button x:Name="Button_Register" Content="Register" HorizontalAlignment="Left"
Margin="183,129,0,0" VerticalAlignment="Top"
Command="Binding Path=GetUserCommand">
<Button.DataContext>
<viewmodels:RegisterViewModel/>
</Button.DataContext>
</Button>
UsersModel.cs
public class UsersModel : ObservableObject
// backing fields
private string _userID;
// Properties
public string UserID // UserID is null
get return _userID;
set
SetProperty(ref _userID, value);
// testing loop for propertychange trigger
public UsersModel()
Task.Run(() =>
while (true)
Debug.WriteLine($"UserID: UserID");
Thread.Sleep(1000);
);
RegisterViewModel.cs
public class RegisterViewModel : ObservableObject
public RelayCommand GetUserCommand get; set;
public RegisterViewModel()
GetUserCommand = new RelayCommand(o =>
// Command is responding to button click.
);
编辑 1 如果我将 ObservableObject.cs 更改为使用 [CallerMemberName] 和 SetProperty,则更新了 UsersModel.cs 中的代码。我还从 RegisterViewModel.cs 中删除了 GetUserCommand 代码,所以我只能测试 UsersModel.cs 中的属性。
据我了解,文本框绑定不起作用。即使使用了 SetProperty 方法,我也没有得到任何价值。
编辑 2
为了澄清,我在一开始就在 XAML(一个 DataContext)中使用了以下内容。但我仍然有同样的问题。 UsersModel 属性没有获取我在文本框中输入的文本。
<UserControl.DataContext>
<models: UserModel/>
</UserControl.DataContext>
我创建了一个带有一个文本框的示例项目,以尝试为文本框设置特定的 DataContext,如下面的代码。它在示例中工作。输出打印我在文本框中写的文本。为什么它在上面的 UsersModel.cs 中不起作用?
MainWindow.xaml
<TextBox HorizontalAlignment="Left" Margin="249,60,0,0"
Text=" Binding SomeText, UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay"
TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.DataContext>
<local:TestModel/>
</TextBox.DataContext>
</TextBox>
TestModel.cs(这很有效,每次我更改文本框中的文本时,我都能看到循环输出)。
class TestModel
private string _someText;
public string SomeText
get return _someText;
set _someText = value;
public TestModel()
Task.Run(() =>
while (true)
Debug.WriteLine(SomeText);
Thread.Sleep(1000);
);
【问题讨论】:
ObservableObject 的文档显示您需要对其调用 SetProperty() 方法来引发通知事件。 ObservableObject。 "提供的 SetPropertyUsersModel User = new()
创建一个新的 UsersModel,与用作 TextBox 的 DataContext 的 UsersModel 完全无关
@quaabaam 即使使用 SetProperty 和使用 [CallerMemberName],我也遇到了同样的问题。但我会调整我的代码,然后再试一次。
@KlausGütter 在 UsersModel.cs 中怎么样,因为我将 UpdateSourceTrigger 设置为 propertychange,所以每次我更新文本框时循环不应该不断更改 UserID 吗?
我不明白这里使用的 2 个上下文。我通常为表单/对话框设置一个上下文并使用那里的属性。第二件事是绑定模式可以设置为TwoWay
,这样可以确保视图可以写回,不确定。
【参考方案1】:
我在错误的地方寻找错误。我设法找到了样式的错误。我已经测试过删除样式并且绑定工作正常。我必须调整我正在使用的主题的代码。感谢所有的cmets。
【讨论】:
以上是关于MVVM WPF:为啥在运行应用程序时更新文本框中的文本后模型中的属性始终为空?的主要内容,如果未能解决你的问题,请参考以下文章
动态地,在运行时,如何在 WPF 中更改文本框中某些单词的颜色?
在 WPF + MVVM +Binding + UserInput 中的 TextBox “预期格式为 DD/MM/YYYY”