1

我注意到在 v3 中,MvvmCross 删除了通用声明<TViewModel>MvxTouchViewController并将其重命名为MvxViewController.

这意味着该ViewModel属性被键入为通用接口IMvxViewModel而不是特定的TViewModel.

如果我需要TViewModel在我的视图控制器中访问,是否有一种方便的方法可以让 ViewModel 已经转换为此视图的特定实例类型?还是我每次都必须自己投?

4

2 回答 2

4

以前基于通用的 MvvmCross 视图已从 MvvmCross 中删除,主要是因为基于目标 C 的平台中的“Heizenbugs”威胁。

对于很少有人知道的内容Heizenbugs,请参阅http://forums.xamarin.com/discussion/771/exporting-generic-type-to-objc-supported

我不相信我见过 Heizenbug,但 Xamarin 在他们的建议中非常明确地建议不惜一切代价避免它们 - 例如,他们两次更改编译器以为我们的泛型发出错误。事实上,在 .Mac 上,这样的通用代码今天仍然是一个错误,而在 .iOS 上,它只是一个非常可怕的警告


除此之外,我们在从通用基类继承时也确实遇到了一些基于 Xaml 的平台的问题——尽管这些问题主要得到了解决(例如,当我从通用基类继承页面时出现 XamlParseException

(除此之外 - 为了允许一些向后兼容性,WindowsPhone 仍然有一些有限的通用视图支持,但这被标记为Obsolete,我很遗憾允许它继续存在......)


好消息是,根据我的经验,大多数 View 不需要知道它们的 ViewModel 类型——相反,大多数 View 可以使用“纯绑定”构建而无需声明类型化的 ViewModel。

对于那些确实需要知道其 ViewModel 类型的剩余视图,然后一个简单的添加属性可以快速添加它 - 例如:

protected MyViewModel MyViewModel
{
    get { return (MyViewModel)base.ViewModel; }
    /* set is optional - not typically needed 
    set { base.ViewModel = value; } 
    */
}

或者,如果您愿意,您可以为此编写扩展方法 - 例如:

public static TViewModel TypedViewModel<TViewModel>(this IMvxView view) where TViewModel : class, IMvxViewModel
{
    return view.ViewModel as TViewModel;
}

非常另类....

.... 如果您不怕鬼、妖精或Heizenbugs....

TypedViewModel属性添加到所有视图的一种方法是将泛型添加回视图层次结构 - 这对你来说很容易 - 例如在 Android 中添加

public class BaseActivity<TViewModel> : MvxActivity 
   where TViewModel : class, IMvxViewModel
{
    protected TViewModel TypedViewModel
    {
        get { return (TViewModel)base.ViewModel; }
        /* set is optional - not typically needed 
        set { base.ViewModel = value; }
        */
    }
}

这对你来说应该很好......但是如果你碰到了一个 Heizenbug,那么我认为没有人能够帮助你。Xamarin 非常明确地反对这种模式——尤其是在基于 objC 的平台上。

于 2013-05-28T16:27:05.240 回答
0

从 3.5 开始,再次支持基于通用的视图,因为显然底层 Xamarin 问题已得到修复。

http://slodge.blogspot.co.uk/2015/01/mvvmcross-v35-pushed-to-stable.html

于 2015-02-20T13:04:22.593 回答