Легкие команды MVVM в ItemsControl - PullRequest
2 голосов
/ 22 мая 2011

Я просто пробую свои силы в WP7 dev с использованием инфраструктуры MVVM Light.

Я пытаюсь запустить команду кнопки внутри 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;
        });
    }

Теперь, как вы можете видеть, я пытаюсь передать текущий объект Car, связанный через CommandParameter. Мой делегат никогда не срабатывает, поэтому я предполагаю, что у меня что-то не так в привязке относительно текущего DataContext.

У кого-нибудь есть идеи относительно того, что я делаю неправильно?

Ответы [ 3 ]

7 голосов
/ 22 мая 2011

В DataTemplate DataContext по умолчанию устанавливается на элемент, представленный DataTemplate (в данном случае, объект Car). Если команда EditCar находится в главной модели представления (которая также содержит коллекцию MyCars), вам необходимо явно установить источник привязки для этого объекта. Это будет (при условии, что вы используете ViewModelLocator для MVVM Light и что ваша виртуальная машина называется Main) {Binding Source = {StaticResource Locator}, Path = Main.EditCar}

Ура, Laurent

1 голос
/ 22 мая 2011

Это собирается выстрелить EditCar на предмете автомобиля. Есть несколько способов решить эту проблему, , так как вы используете mvvm light, попробуйте .

Извинения перед Лораном. Я разместил неправильную ссылку. Я предполагал, что, поскольку оригинальный постер использовал MVVM Light, подойдет DataContextProxy Дана Уолина или RelativeSource для связывания . Я собирался продолжить и объяснить, как, если бы с помощью CM могло всплыть событие из дочернего элемента, но я этого не сделал. Ссылку на CM dotnetrocks я вставил ранее.

0 голосов
/ 28 мая 2011

Я обнаружил, что намного проще делать коллекции VM коллекциями, а не коллекциями Entity.Раньше я использовал подборки сущностей, а затем столкнулся с теми проблемами, которые вы описываете.Но теперь каждая виртуальная машина в Коллекции является «самосознающей» и может действовать сама по себе, не перепрыгивая через большие обручи.

У вас будет кнопка, которую вы нажимаете, как часть CarsVM, и она будет иметь доступ ко всем свойствам carVM, которые будут иметь доступ ко всем свойствам вашего Car Entity.

Образец из моего приложения:

 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:

 public CollectionViewSource SearchResultsCVS { get; private set; }

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

Коллекция является источником CVS .....При нажатии кнопки completeSurveyButton отправляется запрос на навигацию, а копия модели представления отправляется любым слушателям для манипулирования.

...