我有以下recyclerview
,其中包含TestViewModel
个对象的列表。在此对象中,我有age
,gender
和name
属性。我试图在用户点击列表项时实现,它需要用户详细查看用户能够更新的位置并单击保存按钮,然后更新所选项属性。
问题:
MainViewModel
中的以下代码,当我收到详细信息中的值并更新每个属性时,我收到来自DetailViewModel
的消息,
private void OnMessageReceived(TestMessage obj)
{
_selectedItem.Age = obj.messageTest.Age;
_selectedItem.Name = obj.messageTest.Name;
_selectedItem.Gender = obj.messageTest.Gender;
}
但是下面这段代码在我试图直接更新对象的地方不起作用。
private void OnMessageReceived(TestMessage obj)
{
_selectedItem= obj.messageTest;
RaisePropertyChanged(() => SelectedItem);
}
代码实施如下:
<MvxRecyclerView
android:id="@+id/TestRecyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
local:MvxBind="ItemsSource TestsViews; ; ItemClick ItemSelected" />
MainViewModel
public MainViewModel SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
ShowViewModel<DetailViewModel>(
new DetailViewModel.Parameter
{
Age = _selectedItem.Age,
Name = _selectedItem.Name,
Gender = _selectedItem.Gender,
});
RaisePropertyChanged(() => SelectedItem);
}
}
public virtual ICommand ItemSelected
{
get
{
return new MvxCommand<TestViewModel>(item =>
{
SelectedItem = item;
});
}
}
private void OnMessageReceived(TestMessage obj)
{
_selectedItem.Age= obj.messageTest.Age;
_selectedItem.Name= obj.messageTest.Name;
_selectedItem.Gender= obj.messageTest.Gender;
}
TestMessage
public class TestMessage : MvxMessage
{
public MainModel messageTest { get; set; }
public TestMessage(object sender, MainModel editTest) : base(sender)
{
messageTest = editTest;
}
}
DetailViewModel
public TestViewModel EditTest
{
get { return _editTest; }
set
{
_editTest = value;
RaisePropertyChanged(() => EditTest);
}
}
public DetailViewModel(IMvxMessenger messenger)
{
_messenger = messenger;
}
public void Save()
{
UpdateValues();
}
public void UpdateValues()
{
var message = new TestMessage(this, _editTest);
_messenger.Publish(message, typeof(TestMessage));
}
public void Init(Parameter param)
{
_editTest = new TestViewModel();
_editTest.Age = param.Age;
_editTest.Name = param.Name;
_editTest.Gender = param.Gender;
public class Parameter
{
public double Age { get; set; }
public int Gender { get; set; }
public string Name { get; set; }
}
DetailView xml
<EditText
style="@style/InputNumbersEditText"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="44dp"
android:gravity="center_vertical|right"
android:hint="00.000"
local:MvxBind="Text EditTest.Age, Converter=Nullable;" />
TestViewModel
public class TestViewModel : BaseViewModel
{
public string? Name { get; set; }
public double? Age { get; set; }
public int? Gender { get; set; }
}
NullableValueConverter
public class NullableValueConverter : MvxValueConverter
{
public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (string.IsNullOrEmpty(value?.ToString()))
{
return parameter;
}
return value;
}
public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || string.IsNullOrEmpty(value.ToString()))
{
return null;
}
return value;
}
}
答案 0 :(得分:3)
private void OnMessageReceived(TestMessage obj)
{
_selectedItem= obj.messageTest;
RaisePropertyChanged(() => SelectedItem);
}
这不起作用,因为您只是将_selectedItem
的引用更改为指向另一个对象。但是此对象未包含在用于在回收器视图中显示的列表中。您不更新对象,只是一个参考!您一定要了解C#的基础知识,以了解这种数据结构。例如。 Reference vs. Value Type
您的代码有点错误。
SelectedItem
的类型为MainViewModel
您的点击命令会获得TestViewModel
public virtual ICommand ItemSelected
{
get
{
return new MvxCommand<TestViewModel>(item =>
{
SelectedItem = item;
});
}
}
通常这应该有效:
private void OnMessageReceived(TestMessage obj)
{
_selectedItem.Age= obj.messageTest.Age;
_selectedItem.Name= obj.messageTest.Name;
_selectedItem.Gender= obj.messageTest.Gender;
}
但是有TestViewModel
之类的
public class TestViewModel : BaseViewModel
{
private string? name;
public string? Name { get{ return name; } set { SetProperty(ref name, value); } }
// same for Age and Gender
}
SetProperty
设置值并调用OnPropertyChanged事件。
答案 1 :(得分:0)
更新了答案
为_selectedItem
分配新的TestViewModel
会将其对TestViewModel
数据源列表中保存的TestsViews
的引用链接断开。分配各个属性时,会保留TestViewModel
列表中原始TestsViews
的引用。
原始回答
在更新支持字段_selectedItem
时,所以当您收到消息事件时,RaisePropertyChanged
属性集中定义的SelectedItem
事件将永远不会运行。您必须手动触发RaisePropertyChanged
才能触发绑定更新。
尝试更改您当前的方法:
private void OnMessageReceived(TestMessage obj)
{
_selectedItem= obj.messageTest;
}
提升属性更改事件:
private void OnMessageReceived(TestMessage obj)
{
_selectedItem = obj.messageTest;
RaisePropertyChanged(() => SelectedItem);
}