C# 使用ListView SelectedItem vs TextCell命令绑定
我有一个场景,需要获取所选TextCell的值,并使用它更新ListView之外的标签。我注意到ListView有一个SelectedItem属性,TextCell有一个Command属性。这两者有什么区别 作为一个更一般的设计问题(我使用的是XamarinMVVM),我应该如何进行更新?目前我正在考虑使用ListView SelectedItem属性并将其与我的VM绑定(双向)。然后在Setter中,我将更新标签绑定到的VM属性。。。。问题是我需要执行一个异步任务,因为它会将TextCell值转换为我需要的标签值。。。。我该怎么做 我看到有人提到行为,但这似乎更多是针对UI(而不是逻辑)。我还考虑了使用Task.Run来解决setter中的异步问题,但很明显,异步项并不适用于setter。此外,我还考虑过使用MessagingCenter,但这似乎适用于VM->VM。TextCell命令似乎合适,但已读取以使用SelectedItems 视图:C# 使用ListView SelectedItem vs TextCell命令绑定,c#,xaml,xamarin,mvvm,xamarin.forms,C#,Xaml,Xamarin,Mvvm,Xamarin.forms,我有一个场景,需要获取所选TextCell的值,并使用它更新ListView之外的标签。我注意到ListView有一个SelectedItem属性,TextCell有一个Command属性。这两者有什么区别 作为一个更一般的设计问题(我使用的是XamarinMVVM),我应该如何进行更新?目前我正在考虑使用ListView SelectedItem属性并将其与我的VM绑定(双向)。然后在Setter中,我将更新标签绑定到的VM属性。。。。问题是我需要执行一个异步任务,因为它会将TextCell值
- 将标签绑定到虚拟机的属性,例如文本
- 将ListView的SelectedItem绑定到VM的属性,我们称之为SelectedItem
- 在SelectedItem的setter中调用Task。运行(()=>DoWork(value))完成工作或获取翻译
- 在工作结束时,设置属性文本
- 文本的属性设置程序应调用PropertyChanged
- 就这样
public class MyViewModel : ViewModelBase {
private string _text;
public string Text {
get => _text;
set {
_text = value;
OnPropertyChanged();
}
}
private YourItemType _selectedItem;
public YourItemType SelectedItem {
get => _selectedItem;
set {
_selectedItem = value;
Task.Run(() => GetValue(value));
OnPropertyChanged();
}
}
private readonly object _lockObject = new object();
private void GetValue(YourItemType item){
if(item == null) {
Text = "invalid";
return;
}
//avoid entering twice here
lock(_lockObject) {
//Do your work here - it's in the background already
Text = resultOfWork;
}
}
}
OnPropertyChanged()是INotifyPropertyChanged的实现。比如:
public class ViewModelBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChangedByName(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void RefreshView() {
foreach (var propertyInfo in GetType().GetRuntimeProperties()) {
OnPropertyChangedByName(propertyInfo.Name);
}
}
}
所以任务。在setter中运行很好。。。很公平。谢谢。Task.Run的目的是将其放在UI以外的其他线程上吗?我一直只在异步方法中使用它。
public class MyViewModel : ViewModelBase {
private string _text;
public string Text {
get => _text;
set {
_text = value;
OnPropertyChanged();
}
}
private YourItemType _selectedItem;
public YourItemType SelectedItem {
get => _selectedItem;
set {
_selectedItem = value;
Task.Run(() => GetValue(value));
OnPropertyChanged();
}
}
private readonly object _lockObject = new object();
private void GetValue(YourItemType item){
if(item == null) {
Text = "invalid";
return;
}
//avoid entering twice here
lock(_lockObject) {
//Do your work here - it's in the background already
Text = resultOfWork;
}
}
}
public class ViewModelBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChangedByName(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void RefreshView() {
foreach (var propertyInfo in GetType().GetRuntimeProperties()) {
OnPropertyChangedByName(propertyInfo.Name);
}
}
}