2016-04-19 12 views
2

Ich arbeite an einer Win10 UWP App mit MVVMLight (ich habe nie MVVMLight verwendet, und nie Befehle "richtig"). Ich habe ein ItemsControl an eine ObservableCollection gebunden. Der Teilnehmer hat zwei Eigenschaften - Name und Runden. Ich habe Kontrollen in der ItemsControl.ItemTemplate, um eine Schaltfläche anzuzeigen (subtrahieren), die Name-Eigenschaft des Elements, die Laps-Eigenschaft des Elements und eine weitere Schaltfläche (hinzufügen). Hier ist der XAML:Binding Befehl zu ItemsControl Item

<ItemsControl 
        ItemsSource="{Binding Participants, Mode= TwoWay}"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <Grid 
           MinWidth="300" 
           Margin="0, 12"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition 
             Width="2*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="6*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="2*"></ColumnDefinition> 
            <ColumnDefinition 
             Width="3*"></ColumnDefinition> 
           </Grid.ColumnDefinitions> 
           <Button 
            Content="&#xE108;" 
            FontFamily="Segoe MDL2 Assets" 
            FontSize="20" 
            Grid.Column="0" 
            Margin="0, 0, 12, 0"></Button> 
           <TextBlock 
            Text="{Binding Path=Name, Mode=TwoWay}" 
            FontSize="20" 
            FontWeight="Bold" 
            Grid.Column="1"></TextBlock> 
           <TextBlock 
            Text="{Binding Laps, Mode=TwoWay}" 
            FontSize="20" 
            FontWeight="Bold" 
            Grid.Column="2"></TextBlock> 
           <Button 
            Content="&#xE710;" 
            FontFamily="Segoe MDL2 Assets" 
            FontSize="20" 
            Command="{Binding AddLapCommand}" 
            CommandParameter="{Binding}" 
            Grid.Column="3" 
            Margin="12, 0, 0, 0"></Button> 
          </Grid> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 

Das Ansichtsmodell erstellt eine ObservableCollection namens Teilnehmer. Ich versuche, den Add-Button (und dann natürlich den Subtraktions-Button) an einen RelayCommand in der VM zu binden. Ich habe einige Dinge ausprobiert, daher kann ich nicht alles posten, was ich hier versucht habe. Hier ist die neueste von dem, was ich habe, (aber es funktioniert immer noch nicht):

public RelayCommand<object> AddLapCommand 
    { 
     get 
     { 
      if (_addLapCommand == null) 
      { 
       _addLapCommand = new RelayCommand<object>((e) => ExecuteAddLapCommand(e)); 
      } 
      return _addLapCommand; 
     } 
    } 

    private void ExecuteAddLapCommand(object o) 
    { 
     throw new NotImplementedException(); 
    } 

Die Intellisense in der XAML sagt mir, dass es nicht die Eigenschaft AddLapCommand in Datenkontext des Typs LapCounter.Model.Participant lösen können . Ich versuche nicht, zur Teilnehmerklasse zu gelangen, sondern zur HomeViewModel-Klasse, dem DataContext der Seite. Ich denke, ich kann sehen, woher es das LapCounter.Model.Participant von dem einzelnen Element in der Sammlung erhält, an das das ItemsControl gebunden ist. Aber ich hatte den Eindruck, dass wenn ein DataContext nicht gefunden werden konnte, er den visuellen Baum fortsetzen würde, bis er den richtigen gefunden hätte. Hier ist die Datacontext in der Seitendeklaration:

DataContext="{Binding Home, Source={StaticResource Locator}}" 

Wie bekomme ich es an der VM für die RelayCommand zu suchen? Was ich tun muss, ist, dass die Schaltfläche den Teilnehmer, den sie darstellt, an den RelayCommand als Parameter sendet, und benutze diesen, um die Laps-Ganzzahl für diesen bestimmten Teilnehmer zu erhöhen (und im Fall der Subtraktions-Schaltfläche zu dekrementieren).

Ich schätze jede Hilfe, die ich bekommen kann. Vielen Dank!

BEARBEITEN Hinzugefügt Teilnehmer Eigenschaft von der VM zu zeigen, weil meine Ansicht nicht aktualisiert wird. Hier ist die Teilnehmer Eigenschaft:

/// <summary> 
    /// The <see cref="Participants" /> property's name. 
    /// </summary> 
    public const string ParticipantsPropertyName = "Participants"; 

    private ObservableCollection<Participant> _participants = new ObservableCollection<Participant>(); 

    /// <summary> 
    /// Sets and gets the Participants property. 
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary> 
    public ObservableCollection<Participant> Participants 
    { 
     get 
     { 
      return _participants; 
     } 

     set 
     { 
      if (_participants == value) 
      { 
       return; 
      } 

      _participants = value; 
      RaisePropertyChanged(() => Participants); 
     } 
    } 

Dank an Eldar Dordzhiev für seine Hilfe bisher!

Antwort

1

Try this:

Command="{Binding Home.AddLapCommand, Source={StaticResource Locator}}" 

Es gibt nicht viel zu Ihnen zu erklären, solange alles, was Sie geschrieben haben, absolut richtig ist.

Für das Inkrementieren/Dekrementieren der Laps, können Sie einfach die in den Befehlshandler übergeben und die Laps ändern. Wenn Sie MVVMLight mit RelayCommand<Participant> verwenden. Vergessen Sie nicht, die in CommandParameter zu passieren.

+0

Danke, Eldar. Das hat dieses Problem gelöst. Jetzt funktioniert mein RelayCommand und die Laps-Eigenschaft des Teilnehmers wird aktualisiert. Jetzt das Problem, das ich habe, ist, dass die Laps-Anzeige in der Ansicht nicht aktualisiert wird. Ich habe den Code aus VM der Participants-Eigenschaft hinzugefügt und implementiert RaisePropertyChanged, aber es funktioniert nicht. Wird die Auflistung RaisePropertyChanged nicht geändert, wenn ein Element in der Auflistung geändert wird? –

+0

Macht nichts - ich habe es dank dieses Beitrags herausgefunden (http://stackoverflow.com/questions/5285377/wpf-mvvm-otify-propertychanged-implementation-model-or-viewmodel). Es funktioniert jetzt. Vielen Dank! –

+0

@RichHopkins Sie müssen 'INotifyPropertyChanged' in der Klasse' Participant' implementieren. Bitte vergiss nicht, meine Antwort als Antwort zu markieren, wenn es dir hilft. –