我需要在页面之间传输数据并对其进行“绑定”。 在第一页上,我将文本框绑定到“用户名”属性。 每个页面都有自己的viewmodel,点击第一页中的按钮后,我就完成了这样的事情
SecondPageViewModel.Username = this.Username;
在第二页中,我将textblock绑定到Username属性,但在页面更改后,第二页显示没有文本。
<TextBlock Text="{Binding Username}" />
我发现和工作的唯一方法是在构造函数的第二页viewmodel中创建一个更新用户名的任务。
Task.Run(async () =>
{
while(true)
{
await Task.Delay(200);
this.Username = FirstPageViewModel.Username;
}
});
还有其他办法吗?通过在这里完成任务,它并不总是有效,有时如果我更快地更改页面,它无论如何都不会显示用户名。
每个viewmodel都实现了INotifyPropertyChanged + FodyWeaver。
答案 0 :(得分:0)
根据我的评论,这是一些使用事件的简单实现。
FirstPageViewModel is parent of SecondPageViewModel
。您可以在SecondPageViewModel
构造函数中看到事件订阅。FirstPageViewModel is on the same level of SecondPageViewModel
。这在两个ViewModel之间使用Mediator。它基本上消除了FirstPageViewModel
SecondPageViewModel
的依赖关系
FirstPageViewModel
上创建您自己的委托,以便SecondPageViewModel
订阅。它与PropertyChanged
基本相同,但您可以配置准备传递的事件参数。这是一个演示:
public delegate void UsernameChangedEventHandler(string username);
public class FirstPageViewModel : INotifyPropertyChanged
{
// 3) Third implementation
public event UsernameChangedEventHandler UsernameChanged;
private string _username;
public string UserName
{
get { return _username; }
set
{
_username = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("UserName"));
if (UsernameChanged != null)
UsernameChanged(this.UserName);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class SecondPageViewModel : INotifyPropertyChanged
{
private string _username;
public string UserName
{
get { return _username; }
set
{
_username = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("UserName"));
}
}
public SecondPageViewModel()
{
}
public SecondPageViewModel(FirstPageViewModel parent)
{
// 1) First implementation
parent.PropertyChanged += FirstPageViewModel_OnPropertyChanged;
// 3) Third Implementation
parent.UsernameChanged += Parent_UsernameChanged;
}
private void Parent_UsernameChanged(string username)
{
this.UserName = username;
}
private void FirstPageViewModel_OnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
FirstPageViewModel parent = (FirstPageViewModel) sender;
if(args.PropertyName.Equals("username", StringComparison.InvariantCultureIgnoreCase))
{
this.UserName = parent.UserName;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class ParentViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private FirstPageViewModel _firstPageViewModel;
private SecondPageViewModel _secondPageViewModel;
public ParentViewModel()
{
// 2) Second implementation
_firstPageViewModel = new FirstPageViewModel();
_secondPageViewModel = new SecondPageViewModel();
_firstPageViewModel.PropertyChanged += FirstPageViewModel_PropertyChanged;
// 3) Third Implementation
_firstPageViewModel.UsernameChanged += FirstPageViewModel_UsernameChanged;
}
private void FirstPageViewModel_UsernameChanged(string username)
{
_secondPageViewModel.UserName = username;
}
private void FirstPageViewModel_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
FirstPageViewModel firstPageViewModel = (FirstPageViewModel)sender;
if (args.PropertyName.Equals("username", StringComparison.InvariantCultureIgnoreCase))
{
_secondPageViewModel.UserName = firstPageViewModel.UserName;
}
}
}