ItemsControl中的MVVM Light命令

时间:2011-05-22 03:28:28

标签: silverlight windows-phone-7 mvvm-light

我只是在使用MVVM Light框架尝试WP7开发。

我正在尝试在ItemsControl中触发一个按钮命令,本质上它是一个汽车列表,我希望每个元素都有一个编辑按钮。 观点的相关部分:

<ItemsControl ItemsSource="{Binding MyCars}" >
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Grid x:Name="CarViewGrid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="100" />
                <ColumnDefinition Width="Auto" MinWidth="302"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="40" />
                <RowDefinition Height="Auto" MinHeight="32" />
                <RowDefinition Height="Auto" MinHeight="32" />
                <RowDefinition Height="Auto" MinHeight="32" />
            </Grid.RowDefinitions>
            <TextBlock x:Name="CarName" Text="{Binding Name, Mode=TwoWay}" Margin="7,0" Grid.Row="0" Grid.ColumnSpan="2" FontSize="32" FontWeight="Bold" FontStyle="Normal" />
            <TextBlock x:Name="Make" Text="{Binding Make, Mode=TwoWay}" Margin="15,0" Grid.Row="1" Grid.Column="0" FontSize="24" />
            <TextBlock x:Name="Model" Text="{Binding Model, Mode=TwoWay}" Grid.Row="1" Grid.Column="1" FontSize="24" />
            <TextBlock x:Name="Odometer" Text="{Binding Odometer, Mode=TwoWay}" Margin="15,0"  Grid.Row="2" Grid.ColumnSpan="2" FontSize="24" />
            <Button x:Name="EditCarButton" Content="Edit" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" Width="100" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <cmd:EventToCommand Command="{Binding EditCar}" CommandParameter="{Binding}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </Grid>
    </DataTemplate>
</ItemsControl.ItemTemplate>

我的ViewModel包含:

    public RelayCommand OpenNewForm { get; private set; }

    public CarViewModel()
    {
        //Snip
        EditCar = new RelayCommand<Car>(c =>
        {
            CurrentCar = c;
            FormVisible = true;
        });
    }

现在您可以看到我正在尝试传递通过CommandParameter绑定的当前Car对象。我的代表从不开火所以我猜我在绑定当前的DataContext时遇到了问题。

有人对我做错了什么有任何想法吗?

3 个答案:

答案 0 :(得分:7)

在DataTemplate中,默认情况下将DataContext设置为由DataTemplate表示的项(在本例中为Car对象)。如果EditCar命令位于主视图模型(也包含MyCars集合)上,则需要显式设置该对象的绑定源。这将是(假设您正在使用MVVM Light的ViewModelLocator并且您的VM名为Main){Binding Source = {StaticResource Locator},Path = Main.EditCar}

干杯, 劳伦

答案 1 :(得分:1)

它将在汽车项目上触发EditCar。有几种方法可以解决这个问题,since you're using mvvm light try

对劳伦特的批评。我发布了错误的链接。我的意图是,由于原始海报使用MVVM Light,Dan Wahlin's DataContextProxyRelativeSource binding解决方案可行。我将继续解释如果使用CM从子项目中发生的事件可能会冒泡但我没有。 CM dotnetrocks的链接是我之前粘贴的。

答案 2 :(得分:0)

我发现它很容易使我的集合VM集合而不是Entitycollections。我曾经使用过entitycollections,然后我开始遇到像你所描述的那些问题。但是现在集合中的每个虚拟机都是“自我意识”,并且可以在不跳过主要环节的情况下自行行动。

您将点击作为CarsVM一部分的按钮,它可以访问carVM的所有属性,这些属性可以访问您的Car Entity的所有属性。

My App中的示例:

 public partial class ReadmitPatientListViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the ReadmitPatientListViewModel class.
        /// </summary>

        ////public override void Cleanup()
        ////{
        ////    // Clean own resources if needed

        ////    base.Cleanup();
        ////}

        #region Declarations

        ICommand _openSurveyCommand;
        Messenger _messenger = Messenger.Default;

        #endregion

        #region Command Properties
        public ICommand OpenSurveyCommand
        {
            get
            {
                if (_openSurveyCommand == null)
                {
                    _openSurveyCommand = new RelayCommand(() => OnSurveyCommandExecute());
                }
                return _openSurveyCommand;
            }
            private set { }
        }
        #endregion

        #region Command Methods
        private void OnSurveyCommandExecute()
        {
            Wait.Begin("Loading Patient List...");
            _messenger.Send<ReadmitPatientListViewModel>(this);
            _messenger.Send<Messages.NavigationRequest<SubClasses.URI.PageURI>>(GetNavRequest_QUESTIONAIRRESHELL());

        }
        #endregion

        #region Properties

        #endregion


        private static Messages.NavigationRequest<SubClasses.URI.PageURI> GetNavRequest_QUESTIONAIRRESHELL()
        {
            Messages.NavigationRequest<SubClasses.URI.PageURI> navRequest =
                new Messages.NavigationRequest<SubClasses.URI.PageURI>(
                    new SubClasses.URI.PageURI(Helpers.PageLinks.QUESTIONAIRRESHELL, System.UriKind.Relative));
            return navRequest;
        }

        partial void OnCreated()
        {

        }
    }

这些是我的Expander绑定的主vm中的属性:

 public CollectionViewSource SearchResultsCVS { get; private set; }

        public ICollection<ViewModel.ReadmitPatientListViewModel> SearchResults { get; private set; }

该集合是CVS的源头.....当点击completeSurveyButton时,会发送一个导航请求,并将视频模型的副本发送给任何要操纵的侦听器。