我放弃了MVP模式,尝试了MVVM和WPF。到目前为止,我通过单击不同的按钮来导航显示不同UserControls的菜单。数据绑定和命令在导航中工作得很好,但是当数据绑定一个文本框时,我遇到了一个问题。
属性总是得到值null,我不知道为什么。我添加了一个命令,在单击按钮时从文本框中获取UserID,并显示包含UserID的MessageBox,只是为了在我尝试其他任何事情之前使其简单。
显示了MessageBox,但它是空的。我添加了一个任务。在UsersModel.cs中运行,这样我就可以看到字符串是否在属性更改上更新,但值为null。
我正在使用一个类ObservableObject来通知OnPropertyChanged。还有一个RelayCommand类,它继承自iccommand。两者似乎都按预期工作,但只有在单击按钮以显示不同的UserControls和关闭应用程序时。下面是来自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更新UsersModel.cs中的代码,将ObservableObject.cs改为使用[CallerMemberName]和SetProperty。我还从RegisterViewModel.cs中删除了GetUserCommand代码,所以我只能在UsersModel.cs中测试属性。
从我的理解是,textBox绑定不工作。我没有得到任何值,即使使用SetProperty方法。
编辑2
为了澄清,我在开始时在XAML中使用了以下内容(一个DataContext)。但我还是有同样的问题。UsersModel属性没有在文本框中获取文本i类型。
<UserControl.DataContext>
<models: UserModel/>
</UserControl.DataContext>
我创建了一个带有一个文本框的示例项目,尝试为文本框设置一个特定的DataContext,如下面的代码所示。它在样品中起作用了。输出将打印我在文本框中写入的文本。为什么它不能在上面的usermodel .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);
}
});
}
}
我在错误的地方寻找错误。我设法找到了样式的错误。我试过去掉这个样式,装订效果很好。我必须调整我正在使用的主题的代码。谢谢大家的评论。