MvvmCross: привязка nint к enum и двусторонняя конвертация - PullRequest
0 голосов
/ 01 июня 2018

Я пытаюсь привязать нативное nint значение UISegmentedControl.SelectedSegment к 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 выполняет самостоятельное перед вызовом виртуальный 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() {}
}

1 Ответ

0 голосов
/ 05 июня 2018

Как вы можете видеть здесь и здесь MvxUISegmentedControlSelectedSegmentTargetBinding уже выполняет преобразование из / в 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;
    }
}

HIH

...