2010-05-11 4 views
1

J'utilise le RelayCommand de MVVM avec succès pour lier les actions à XAML, mais je vais avoir un petit problème avec mon ItemsControl.RelayCommand expéditeur de l'article ItemsControl

<ItemsControl ItemsSource="{Binding Devices}" > 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Grid Width="100" Margin="4" > 
        <Button Command="{Binding Path=SelectDeviceCommand}" > 
         <Grid> 
          <Image Source="img_small.png"></Image> 
          <Image Source="{Binding Path=Logo}" /> 
         </Grid> 
        </Button> 
       </Grid> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

Dans mon modèle de vue:

public RelayCommand SelectDeviceCommand { get; set; } 
    private ObservableCollection<Device> Devices; 

    Devices = CreateListOfDevices(); 

    private void InitializeCommands() 
    { 
     SelectDeviceCommand = new RelayCommand((s) => MessageBox.Show(s.ToString())); 
    } 

Comment définir mon SelectDeviceCommand dans mon modèle de vue afin de recevoir l'objet qui est lié à cet article?

Mon SelectDeviceCommand est même pas appelé ... (mais que je pense est parce que je dois faire mon appareil un mini-viewmodel et mettre en œuvre la SelectDeviceCommand en elle, est-ce pas?)

Répondre

4

Si vous utilisez un ViewModelLocator comme dans MVVM applications légères, vous pouvez obtenir une référence à l'MainViewModel à l'intérieur du DataTemplate avec

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}"> 

Je trouve cette façon plus propre que le ElementName un, mais bien sûr, il suppose que la propriété Main est disponible dans le localisateur et que le MainviewModel est instancié en tant que singleton. Ce n'est pas toujours possible, évidemment. Dans ce cas, je considère que la solution de contournement ElementName est acceptable.

En WPF, vous pouvez également utiliser un RelativeSource avec mode = FindAncestor, mais je trouve même messier;)

En ce qui concerne la question « Comment puis-je définir mon SelectDeviceCommand dans mon modèle de vue afin de recevoir objet ? est lié à cet élément », je ne suis pas 100% sûr que je comprends la question, mais si vous voulez obtenir l'élément (dans ce cas, un appareil) qui est représenté par le DataTemplate, vous devez utiliser le CommandParameter:

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}" 
     CommandParameter="{Binding}"}"> 

Cheers, Laurent

0

Ouais, je J'ai frappé celui-ci. Je l'ai vu certaines personnes travaillent autour d'elle avec une coutume classe « CommandReference » qu'ils ajoutent comme une ressource à la fenêtre, mais je ne pouvais pas que pour travailler.

En fin de compte, je élément de liaison utilisé retour à la fenêtre (ou pages) elle-même, puisque le ViewModel est le DataContext de la fenêtre. Tout d'abord, donnez votre fenêtre (ou une page) un nom:

<Window ... 
    x:Name="me" /> 

Rabattre au datacontext de la fenêtre directement, comme ceci:

<Button Command="{Binding DataContext.SelectDeviceCommand,ElementName=me}"> 

Cela a fonctionné pour moi. C'est en désordre, mais je pense que c'est assez lisible.

0

J'ai un usercontrol (x: Name = « ControlClass ») et il est à l'intérieur d'un modèle, il ne marche pas travailler sur XAML je l'ai appelé comme ça

<Button Content="New1" Command="{Binding DataContext.NewTabCommand,ElementName=ControlClass}"/> 



namespace Doit_Project.Modules.Tasks.ViewModels 
{ 
    [Export] 
    public class WindoTabViewModel : Doit_ProjectViewModelBase 
    { 
     public WindoTabViewModel() 
     { 

     } 

     private RelayCommand _newTabCommand; 
     public RelayCommand NewTabCommand 
     { 
      get { return _newTabCommand ?? (_newTabCommand = new RelayCommand(OnNewTab)); } 
     } 

     public void OnNewTab() 
     { 

     } 
    } 
}