【问题标题】:Best way to have single View/ViewModel/Xaml link to multiple Json resource files in MvvmCross将单个 View/ViewModel/Xaml 链接到 MvvmCross 中的多个 Json 资源文件的最佳方法
【发布时间】:2013-05-09 21:46:30
【问题描述】:

在我的应用程序中,我有许多帮助页面,它们都有类似的布局 - 标题和正文。

按照我目前的结构方式,对于每个单独的帮助页面,我都有一个 View、ViewModel、.xaml 和 .json 文件。

问题是我的应用程序已经膨胀到有大约 20 个帮助页面(不要问),并且为每个帮助文件复制和粘贴这些页面显然效率低下且容易出错。我想要的是一个单独的 HelpViewModel、HelpView、Page_Help.xml,然后为每个帮助页面创建一个包含相关文本资源的不同 .json 文件。

尽管浏览了现有的 MvvmCross 主题,但我无法弄清楚如何实现这一点。

所以我的 XAML 有一个如下所示的标题:

<TextView
  style="@style/HelpTextTitle"
  local:MvxBind="{'Text':'Path':'TextSource','Converter':'Language','ConverterParameter':'Heading1'}}"
/>

与 ViewModel 同名的 json 文件(并通过某种自动魔术链接)如下所示:

{
  "Heading1":"Sample Help Heading",
}

我有一个可以接受参数的 HelpViewModel - 说出 json 文件的名称

public string HeaderFile { get; private set; }
public HelpViewModel (string headerFile)
{
  HeaderFile = headerFile;
}

json 文件目前通过这个类与我认为的 ViewModel 相关联:

public class TextProviderBuilder : MvxTextProviderBuilder
...
    protected override IDictionary<string, string> ResourceFiles
    {
        get
        {
            var dictionary = this.GetType()
                .Assembly
                .GetTypes()
                .Where(t => t.Name.EndsWith("ViewModel"))
                .Where(t => !t.Name.StartsWith("Base"))
                .ToDictionary(t => t.Name, t => t.Name);

            dictionary[Constants.Shared] = Constants.Shared;
            return dictionary;
        }
    }         

并且主应用程序将其注册为文本提供程序(因此促进了我假设的 ViewModel-Json 文件自动化),如下所示:

var builder = new TextProviderBuilder();
this.RegisterServiceInstance<IMvxTextProvider>(builder.TextProvider);

所以很明显,我想以某种方式使用相同的 HelpPage 资源,但能够将该帮助页面上的控件与(最好)具有与参数 (Header1) 相同名称的不同 json 文件绑定,或者在必要时使用不同的单个 json 文件中的参数。

非常感谢!

马修


编辑:以下 Stuart 的解决方案完美运行。当我通过 ViewModel 的构造函数调用 RequestNavigate 时,我只需要传递 json 文件的名称:

return new MvxRelayCommand(() => this.RequestNavigate<GeneralHelpViewModel>(new { helpKey = "DescribeAudioCrimeStatementHelpViewModel" }));

我唯一需要做的就是创建自己的 MvxLanguageBinder,因为在我的 MvvmCross(不是最近)的确切构建中,MvxLanguageBinder 是私有的且不可访问。

我只是复制并粘贴了 Stuart 链接中的版本并使用了该版本:

https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Localisation/MvxLanguageBinder.cs

【问题讨论】:

  • 我猜你的意思是 AXML 不是 XAML :)
  • Xaml Axml Shmaml 这对我来说都是一样的 ;)

标签: c# android xamarin.android xamarin mvvmcross


【解决方案1】:

有几种方法可以实现这种效果。

如果您想继续使用单独的 json 文件,我可能会采用类似...的方法

更改您的绑定以使用新的 TextSource - CustomTextSource

<TextView
       style="@style/HelpTextTitle"
       local:MvxBind="{'Text':'Path':'CustomTextSource','Converter':'Language','ConverterParameter':'Heading1'}}"
 />

创建您的HelpViewModel,以便它使用导航参数加载此CustomTextSource

 public HelpViewModel (string helpKey)
 {
       CustomTextSource = new MvxLanguageBinder(Constants.GeneralNamespace, helpKey);
 }

 public IMvxLanguageBinder CustomTextSource { get; private set; }

更改执行文本资源加载的代码以包含您的帮助文件。

protected override IDictionary<string, string> ResourceFiles
{
    get
    {
        var dictionary = this.GetType()
            .Assembly
            .GetTypes()
            .Where(t => t.Name.EndsWith("ViewModel"))
            .Where(t => !t.Name.StartsWith("Base"))
            .ToDictionary(t => t.Name, t => t.Name);

        dictionary[Constants.Shared] = Constants.Shared;

        foreach (var additional in HelpFileList)
        {
             dictionary(additional) = additional;
        } 

        return dictionary;
    }
}  

(我在这里假设HelpFileList 是一个静态列表,但您也可以使用反射来做这件事。)


或者,如果您想将帮助 json 重新组织到一个文件中,您还可以考虑编写一个自定义的 IMvxLanguageBinder 来使用您的帮助键。假设您使用的是 vNext,那么 MvxLanguageBinder 的代码应该可以相当直接地适应 - 来自 axml 的调用进入 line 58


或者,如果这真的只是帮助文本,那么您可以考虑放弃这种 xml 和 json 方法 - 您可以改用在 Web 浏览器小部件中显示的嵌入式 HTML - 这可能是最灵活的长期解决方案,它允许以便将来更轻松地更新内容。

【讨论】:

  • 谢谢斯图尔特。我尝试了您的示例,但遇到了一个问题,因为 MvxLanguageBinder 是 MvxApplicationObject 上的私有类。我找到了 MvxLanguageBinder 的源代码并复制了它,但遇到了另一个问题,因为 MvxLanguageBinder 调用了私有方法 MvxApplicationObject.GetText。我是否认为这种方法仅适用于您的框架的最新版本?我认为我正在使用 v2
  • 假设您使用的是 v2/vnext 那么这是源代码吗? github.com/slodge/MvvmCross/blob/vnext/Cirrious/… - 这里的私有方法是什么?困惑 - 也许尝试更新问题(cmets 太小)
  • 哇它好用!谢谢斯图尔特!顺便说一句,我认为在我的 MvvmCross 构建中,MvxLanguageBinder 看起来更像这样:github.com/Zoldeper/Blooor/blob/master/Cirrious.MvvmCross/…
  • 酷 :) 如果你在 master 上,那么你在 v1 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多