将CalendarView DateChange事件与MvvmCross绑定

时间:2017-01-07 23:59:43

标签: xamarin mvvmcross

我有一个看起来像这样的CalendarView:

<CalendarView
  android:layout_width="match_parent"
  android:layout_height="300dp"
  android:id="@+id/createReservationCalendarView" />

以下是我在没有MvvmCross的情况下处理DateChange事件的方法:

protected override void OnCreate(Bundle savedInstanceState)
{
... Code ...

    calendar.DateChange += (s, args) =>
    {
        var year = args.Year;
        var month = args.Month + 1;
        var dayOfMont = args.DayOfMonth;

        var date = new DateTime(year, month, dayOfMont);

        var myReservations = new Intent(this, typeof(CreateReservationTimeslotScreen));
        myReservations.PutExtra("selectedDate", date.Ticks);
        StartActivity(myReservations);
    };
}

现在我已切换到MvvmCross,我希望让我的ViewModel启动新活动。

我不知道如何做到这一点,因为ViewModel应该是OS和UI不可知的。

&#34; args&#34;参数是CalendarView.DateChangeEventArgs类型,这是Android特定的,所以我不能在ViewModel中使用它。它派生自System.EventArgs,所以也许我可以使用它。我认为必须有一个更简单的方法。

我想到的是,是否可以从活动更新ViewModel上的属性,然后从那里执行切换到新的Activity?我不确定如何实现这一点,因为活动没有引用他们的ViewModel。

有什么建议吗?

感谢。

1 个答案:

答案 0 :(得分:0)

MvvmCross确实可以让您从View中访问ViewModel。您的View(例如Android中的Activity / fragment)和ViewModel之间的关系,以及它们在两个方向上共享数据(模型)的能力是Mvvm框架的核心特征。

要设置要与MvvmCross一起使用的活动,您需要确保继承MvxActivityMvxAppCompatActivity(如果使用Android支持库)。在此之后,您需要使用一种可能的约定将您的Activity链接到其对应的ViewModel(请参阅link,以获取MvxViewModelViewTypeFinder提供的每个注册的基本示例)。一个简单的例子是使用类型参数重载来使用基于具体类型的注册。

public class FirstActivity : MvxAppCompatActivity<FirstViewModel>

现在您可以从View中访问ViewModel,您可以创建一个可用于执行导航的命令:

CalendarViewModel (ViewModel链接到当前有关的活动)

创建一个需要DateTime参数的命令,该参数将在导航时传递该值(有关替代导航和参数传递约定,请参阅MvvmCross Navigation docs)。

public class CalendarViewModel : MvxViewModel
{

    IMvxCommand _goToMyReservationCommand;
    public IMvxCommand GoToMyReservationCommand =>
        _goToMyReservationCommand ?? 
        (_goToMyReservationCommand = new MvxCommand<DateTime>(NavigateToMyReservation));

    void NavigateToMyReservation(DateTime reservationDate)
    {
        ShowViewModel<MyReservationViewModel>(
            new GoToMyReservationParameter
            {
                ReservationTicks = reservationDate.Ticks
            });
    }
}

导航参数类

保存用于导航的值和类型信息。

public class GoToMyReservationParameter
{
    public long ReservationTicks { get; set; }
}

<强> MyReservationViewModel

将接收传递值的ViewModel。

public class MyReservationViewModel : MvxViewModel
{
    public void Init(GoToMyReservationParameter parameters)
    {
        var reservationTicks = parameters.ReservationTicks;

        // Do what you need with the parameters
    }
}

<强> 查看

在ViewModel上执行命令并传递DateTime对象。

public class CalendarActivity : MvxAppCompatActivity<CalendarViewModel>
{
    protected override void OnCreate(Bundle bundle)
    {
        ... Code...

        calendar.DateChange += (s, args) =>
        {
            var year = args.Year;
            var month = args.Month + 1;
            var dayOfMont = args.DayOfMonth;

            var date = new DateTime(year, month, dayOfMont);

            ViewModel.GoToMyReservationCommand.Execute(date);
        };
    }
}