MvvmCross:将 nint 绑定到枚举并将其双向转换
MvvmCross: Binding nint to enum and converting it two-way
我正在尝试将 UISegmentedControl.SelectedSegment
的本机 nint
值绑定到视图模型中的 enum
属性。它需要自定义值转换器,因为无法将 enum
直接转换为 nint
,反之亦然。
Convert
方法工作正常,因此 UISegmentedControl
从视图模型中选取值。但是当我单击控件的段时,会引发以下异常:
(MvvmCross.Converters.MvxValueConverter) Failed to ConvertBack from System.nint to MyApp.Core.ViewModels.MyViewModel+Selection with Exception: System.InvalidCastException: Specified cast is not valid.
at MvvmCross.Converters.MvxValueConverter`2[TFrom,TTo].ConvertBack (System.Object value, System.Type targetType, System.Object parameter, System.Globalization.CultureInfo culture)
好像是MvxValueConverter
casts on its own before calling the virtual ConvertBack
方法。除了使视图模型使用 const nint
值而不是单个 enum
.
之外,我不确定有什么解决方法
public partial class MyView : MvxTableViewController<MyViewModel>
{
// SegmentedControl is iOS UISegmentedControl in .designer.cs
public MyView() : base("MyView", null) {}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(SegmentedControl).To(vm => vm.SelectedSegment).WithConversion(new SelectionValueConverter());
set.Apply();
}
public class SelectionValueConverter : MvxValueConverter<MyViewModel.Selection, nint>
{
protected override nint Convert(MyViewModel.Selection value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value; // called
}
protected override MyViewModel.Selection ConvertBack(nint value, Type targetType, object parameter, CultureInfo culture)
{
var intVal = (int)value; // never called, exception in MvxValueConverter[TFrom,TTo].ConvertBack
return (MyViewModel.Selection)intVal;
}
}
}
public class MyViewModel : MvxViewModel
{
public enum Selection
{
One = 0,
Two = 1,
Three = 2
}
Selection _selectedSegment;
public Selection SelectedSegment
{
get => _selectedSegment;
set => SetProperty(ref _selectedSegment, value);
}
public MyViewModel() {}
}
如您所见,here and here MvxUISegmentedControlSelectedSegmentTargetBinding
已经进行了转换 from/to nint
。所以你的转换器应该直接 int
而不是 nint
public class SelectionValueConverter : MvxValueConverter<MyViewModel.Selection, int>
{
protected override int Convert(MyViewModel.Selection value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value;
}
protected override MyViewModel.Selection ConvertBack(int value, Type targetType, object parameter, CultureInfo culture)
{
return (MyViewModel.Selection)value;
}
}
高
我正在尝试将 UISegmentedControl.SelectedSegment
的本机 nint
值绑定到视图模型中的 enum
属性。它需要自定义值转换器,因为无法将 enum
直接转换为 nint
,反之亦然。
Convert
方法工作正常,因此 UISegmentedControl
从视图模型中选取值。但是当我单击控件的段时,会引发以下异常:
(MvvmCross.Converters.MvxValueConverter) Failed to ConvertBack from System.nint to MyApp.Core.ViewModels.MyViewModel+Selection with Exception: System.InvalidCastException: Specified cast is not valid.
at MvvmCross.Converters.MvxValueConverter`2[TFrom,TTo].ConvertBack (System.Object value, System.Type targetType, System.Object parameter, System.Globalization.CultureInfo culture)
好像是MvxValueConverter
casts on its own before calling the virtual ConvertBack
方法。除了使视图模型使用 const nint
值而不是单个 enum
.
public partial class MyView : MvxTableViewController<MyViewModel>
{
// SegmentedControl is iOS UISegmentedControl in .designer.cs
public MyView() : base("MyView", null) {}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(SegmentedControl).To(vm => vm.SelectedSegment).WithConversion(new SelectionValueConverter());
set.Apply();
}
public class SelectionValueConverter : MvxValueConverter<MyViewModel.Selection, nint>
{
protected override nint Convert(MyViewModel.Selection value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value; // called
}
protected override MyViewModel.Selection ConvertBack(nint value, Type targetType, object parameter, CultureInfo culture)
{
var intVal = (int)value; // never called, exception in MvxValueConverter[TFrom,TTo].ConvertBack
return (MyViewModel.Selection)intVal;
}
}
}
public class MyViewModel : MvxViewModel
{
public enum Selection
{
One = 0,
Two = 1,
Three = 2
}
Selection _selectedSegment;
public Selection SelectedSegment
{
get => _selectedSegment;
set => SetProperty(ref _selectedSegment, value);
}
public MyViewModel() {}
}
如您所见,here and here MvxUISegmentedControlSelectedSegmentTargetBinding
已经进行了转换 from/to nint
。所以你的转换器应该直接 int
而不是 nint
public class SelectionValueConverter : MvxValueConverter<MyViewModel.Selection, int>
{
protected override int Convert(MyViewModel.Selection value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value;
}
protected override MyViewModel.Selection ConvertBack(int value, Type targetType, object parameter, CultureInfo culture)
{
return (MyViewModel.Selection)value;
}
}
高