从网格中选择项目时如何调用MvxCommand / ICommand?

时间:2014-01-28 13:10:11

标签: c# wpf xaml xamarin mvvmcross

我正在享受N + 1DaysOfMVVMCross,但我被困在第5天(第2天和第5天的组合)......

我使用第2天开发网格视图UI,并希望使用第5天信息添加一个命令,该命令将在从网格中选择项目时打开辅助视图。 ViewModel中的命令代码从不执行(尽管它确实从按钮执行)。

我认为这个问题与WPF / XAML有关,但我认为我会参考MVVMCross,因为这是我遇到障碍的地方。

感谢您提供任何帮助/提示/指示

一些源代码怎么样......

从视图模型中,抱歉列表初始化我正在慢慢解决这个问题。

using Cirrious.MvvmCross.ViewModels;
using System.Collections.Generic;
using TeleBacteriology.Core.Services;

namespace TeleBacteriology.Core.ViewModels
{
    public class WorklistViewModel : MvxViewModel
    {
        public WorklistViewModel(IWorklistItemService service)
        {
            var newList = new List<WorklistItem>();

            WorklistItem newWorklistItem = service.CreateNewWorklistItem("201401250001", "http://placekitten.com/301/301");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250002", "http://placekitten.com/302/302");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250003", "http://placekitten.com/303/303");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250004", "http://placekitten.com/304/304");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250005", "http://placekitten.com/305/305");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250006", "http://placekitten.com/306/306");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250007", "http://placekitten.com/307/307");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250008", "http://placekitten.com/308/308");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250009", "http://placekitten.com/309/309");
            newList.Add(newWorklistItem);

            newWorklistItem = service.CreateNewWorklistItem("201401250010", "http://placekitten.com/310/310");
            newList.Add(newWorklistItem);

            Worklist = newList;
        }

        private List<WorklistItem> _worklist;
        public List<WorklistItem> Worklist
        {
            get { return _worklist; }
            set { _worklist = value; RaisePropertyChanged(() => Worklist); }
        }

        private MvxCommand _detailsCommand;
        public System.Windows.Input.ICommand DetailsCommand
        {
            get
            {
                _detailsCommand = _detailsCommand ?? new MvxCommand(DoDetailsCommand);
                return _detailsCommand;
            }
        }

        private void DoDetailsCommand()
        {
            ShowViewModel<PlateDetailsViewModel>();
        }
    }
}

视图的XAML:

<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="TeleBacteriology.Store.Views.WorklistView"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TeleBacteriology.Store.Views"
    xmlns:common="using:TeleBacteriology.Store.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>

        <!-- Collection of items displayed by this page -->
        <CollectionViewSource
            x:Name="itemsViewSource"
            Source="{Binding Worklist}"/>

        <DataTemplate x:Key="Worklist250x250ItemTemplate">
            <Grid HorizontalAlignment="Left" Width="250" Height="250">
                <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                    <Image Source="{Binding ImageUrl}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
                </Border>
                <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
                    <TextBlock Text="{Binding AccessionNum}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
                    <TextBlock Text="{Binding ImageUrl}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="Worklist80ItemTemplate">
            <Grid Margin="6">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
                    <Image Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
                </Border>
                <StackPanel Grid.Column="1" Margin="10,0,0,0">
                    <TextBlock Text="{Binding AccessionNum}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/>
                    <TextBlock Text="{Binding ImageUrl}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">My Application</x:String>
    </Page.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Style="{StaticResource LayoutRootStyle}">
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Horizontal scrolling grid used in most view states -->
        <GridView
            x:Name="itemGridView"
            AutomationProperties.AutomationId="ItemsGridView"
            AutomationProperties.Name="Items"
            TabIndex="1"
            Grid.RowSpan="2"
            Padding="116,136,116,46"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
            ItemTemplate="{StaticResource Worklist250x250ItemTemplate}"
            SelectionMode="None"
            IsSwipeEnabled="false"
            SelectedItem="{Binding DetailsCommand}"/>

        <!-- Vertical scrolling list only used when snapped -->
        <ListView
            x:Name="itemListView"
            AutomationProperties.AutomationId="ItemsListView"
            AutomationProperties.Name="Items"
            TabIndex="1"
            Grid.Row="1"
            Visibility="Collapsed"
            Margin="0,-10,0,0"
            Padding="10,0,0,60"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
            SelectedItem="{Binding DetailsCommand}"
            ItemTemplate="{StaticResource Worklist80ItemTemplate}"
            SelectionMode="None"
            IsSwipeEnabled="false"/>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
            <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/>
        </Grid>
        <Grid Grid.Row="2">
            <Button Content="Go Details" Command="{Binding DetailsCommand}" />

        </Grid>

        <VisualStateManager.VisualStateGroups>

            <!-- Visual states reflect the application's view state -->
            <VisualStateGroup x:Name="ApplicationViewStates">
                <VisualState x:Name="FullScreenLandscape"/>
                <VisualState x:Name="Filled"/>

                <!-- The entire page respects the narrower 100-pixel margin convention for portrait -->
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="96,136,86,56"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>

                <!--
                    The back button and title have different styles when snapped, and the list representation is substituted
                    for the grid displayed in all other view states
                -->
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</common:LayoutAwarePage>

我可以发布第二个视图,但我不认为这是必要的。同样,如果我在视图中放置一个按钮并将Command绑定设置为DetailsCommand,则第二个视图弹出就好了。无法使其与网格上的项目选择一起使用。

1 个答案:

答案 0 :(得分:1)

从查看代码开始,您似乎误解了ListView的SelectedItem属性。当选择更改时,将使用您的一个WorkListItem对象填充它。

ListView没有像Button那样的命令属性,因此您需要处理ListView的SelectionChanged事件并手动调用Viewmodel上的Command。

您可以在代码隐藏中执行此操作,或者查看其中一个EventToCommand帮助程序,直接在xaml中执行此操作。