MvvmCross vnext:monodroid CommandParameter类似于wp7

时间:2012-10-15 09:23:22

标签: c# windows-phone-7 xamarin.ios xamarin.android mvvmcross

我在Tutorial示例的MainMenuView中使用Dictionary而不是List。在wp7中,我这样绑定:

 <ListBox ItemsSource="{Binding Items}" x:Name="TheListBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Key}" Margin="12" FontSize="24" TextWrapping="Wrap">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <commandbinding:MvxEventToCommand Command="{Binding Path=DataContext.ShowItemCommand, ElementName=TheListBox}" CommandParameter="{Binding Value}" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

但是对于monodroid,我不知道在哪里放置CommandParameter =&#34; {Binding Value}&#34;在mvxListView中,我收到此错误:&#34; MvxBind:错误:2,71从Items到ItemsSource的绑定执行过程中出现问题 - 问题ArgumentException:无法转换参数&#34;来自我的axml代码:

<Mvx.MvxBindableListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/Tutorial.UI.Droid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="{'ItemsSource':{'Path':'Items'},'ItemClick':{'Path':'ShowItemCommand'}}"
local:MvxItemTemplate="@layout/listitem_viewmodel"

/&GT;

如何在wp7中设置CommandParameter属性?

提前感谢您的帮助。

按照您的指示1,我在Tutorial.Core中更改MainMenuViewModel,如下所示:

`public Dictionary Items {get;组; }

    public ICommand ShowItemCommand
    {
        get
        {
            return new MvxRelayCommand<KeyValuePair<string, Type>>((type) => DoShowItem(type.Value));
        }
    }

    public void DoShowItem(Type itemType)
    {
        this.RequestNavigate(itemType);
    }

    public MainMenuViewModel()
    {
        Items = new Dictionary<string, Type>()
                    {
                        {"SimpleTextProperty",  typeof(Lessons.SimpleTextPropertyViewModel)},
                        {"PullToRefresh",  typeof(Lessons.PullToRefreshViewModel)},
                        {"Tip",  typeof(Lessons.TipViewModel)},
                        {"Composite",typeof(Lessons.CompositeViewModel)},
                        {"Location",typeof(Lessons.LocationViewModel)}
                    };
    }`

示例在wp7中按预期工作,但是使用monodroid我会得到与前一个相同的错误,因为我认为KeyValuePair Key属性会导致问题:

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:local="http://schemas.android.com/apk/res/Tutorial.UI.Droid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
          android:layout_margin="12dp"
        android:orientation="vertical">
<TextView
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="View Model:"
        />
  <TextView
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:textAppearance="?android:attr/textAppearanceLarge"
          local:MvxBind="{'Text':{'Path':'Key'}}"
        />
</LinearLayout>

1 个答案:

答案 0 :(得分:1)

Mvx目前没有单独的CommandParameter依赖关系目标,因此您目前无法以相同的方式解决此问题。

不包含CommandParameters的原因是设计选择,并且与缺乏行为有关。因为没有行为对象围绕控件事件将命令和命令参数包装在一起,所以Click,LongClick,Swipe等需要单独的CommandParameter绑定 - 这些可能会变得非常冗长和丑陋 - 所以,到目前为止,我们已经避开了这种方法。

但是,有几种方法可以达到与您正在寻找的效果类似的效果。


首先,列表上的ItemClick事件始终绑定,以便参数始终是已单击的对象 - 因此,如果您可以在MvxRelayCommand操作中执行.Value投影,那么代码将同时工作在WP7和MonoDroid中。

即。这可以实现:

<ListBox ItemsSource="{Binding Items}" x:Name="TheListBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Key}" Margin="12" FontSize="24" TextWrapping="Wrap">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Tap">
                            <commandbinding:MvxEventToCommand Command="{Binding Path=DataContext.ShowItemCommand, ElementName=TheListBox}" CommandParameter="{Binding}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBlock>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

使用:

<Mvx.MvxBindableListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/Tutorial.UI.Droid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="{'ItemsSource':{'Path':'Items'},'ItemClick':{'Path':'ShowItemCommand'}}"
local:MvxItemTemplate="@layout/listitem_viewmodel"
/>

您的命令处理程序执行.Value的工作:

public ShowItemCommand {        get {return new MvxRelayCommand(item =&gt; {DoShowFor(item.Value);}); }    }


其次,您可以选择绑定到每个列表项中的视图/控件上的Click事件,而不是绑定到List级事件。有关此问题的一些讨论,请参阅MVVMCross changing ViewModel within a MvxBindableListView

上的答案

第三,你可以在这种情况下编写你自己的绑定,如果你真的想......我觉得这种情况会有些过分,但在其他情况下可能会有用。


有关更多列表选择示例,请查看BestSellers和CustomerManagement示例。