2010-09-11 5 views
1

alt text Bonjour,boutons WPF sont en dehors du datacontext et ne pouvaient pas être liés

J'ai 3 boutons ajouter, supprimer, ouvrir comme RelayCommands dans mon DocumentViewModel. Ci-dessous vous voyez comment je les ai liés. Bien sûr, ceux liant ne fonctionne pas, car les données sont mis à la ItemsSource du ListBox et les boutons sont en dehors de cette ...

Ce que j'ai essayé alors est de mettre DataContext au premier StackPanel que vous voyez dans mon extrait de code.

comme ceci: <StackPanel DataContext="{Binding DocumentViewModelList}" >

mais un nouveau problème arised ... maintenant les documents ne sont pas visibles/plus répertoriés dans la zone de liste:/

Comment puis-je faire les deux travailler?

<StackPanel Orientation="Vertical" > 
              <ListBox 
               Height="100" 
               Width="Auto" 
               Focusable="True" 
               ScrollViewer.HorizontalScrollBarVisibility="Auto" 
               ScrollViewer.VerticalScrollBarVisibility="Auto" 
               Grid.Row="1" 
               Name="itemListBox" 
               BorderThickness="1"  
               ItemsSource="{Binding DocumentViewModelList}" 
               > 
               <ListBox.ItemTemplate> 
                <DataTemplate> 
                 <StackPanel>  
                  <!-- xxx --> 
                  <TextBlock Text="{Binding Path=Name}" /> 
                 </StackPanel> 
                </DataTemplate> 
               </ListBox.ItemTemplate> 
               <ListBox.ItemContainerStyle>             
                 <Style TargetType="{x:Type ListBoxItem}"> 
                  <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" /> 
                 </Style>             
               </ListBox.ItemContainerStyle> 
              </ListBox> 
              <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">             
               <Button Command="{Binding DeleteDocumentCommand}" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Content="Delete" /> 
               <Button Command="{Binding AddDocumentCommand}" HorizontalAlignment="Stretch" Content="Add" /> 
               <Button Command="{Binding OpenDocumentCommand}" HorizontalAlignment="Stretch" Content="Open" />            
              </StackPanel> 
             </StackPanel> 

MISE À JOUR:

J'ai essayé:

<Button Command="{Binding Path=DeleteDocumentCommand, RelativeSource={RelativeSource AncestorType={x:Type DocumentViewModel}}}" 

et a ce: La référence de type ne peut pas trouver un type public nommé 'DocumentViewModel'

Je voudrais rester avec la solution StackPanel DataContext et faire en sorte que ListBox.ItemsSource saisisse DocumentViewModelList via la liaison RelativeSource avec FindAncestor. J'ai essayé certaines choses mais pas de chance, peut-être que quelqu'un peut poster un bon extrait :)

OK J'ai trouvé la solution: <ListBox ItemsSource="{Binding}" ...

Ceci est lié au DataContext actuel qui est "DocumentViewModelList" cool!

MISE À JOUR 2:

ok il y a encore un autre problème, peut-être si quelqu'un peut fournir une solution sur ce je marque ce fil comme une solution alors. Vous ne voulez pas ouvrir un nouveau thread, car tout le texte + extrait de code est le même ... Le problème est maintenant => La sélection du 1er document active le bouton. Sélectionner un autre bouton n'active pas un bouton, POURQUOI? Quel est le problème avec la liaison de ma propriété IsSelected?

DocumentViewModel.cs:

private bool _isSelected; 
     public bool IsSelected 
     { 
      get { return _isSelected; } 
      set 
      { 
       if (_isSelected == value) 
        return; 

       _isSelected = value; 
       this.RaisePropertyChanged("IsSelected"); 
      } 
     } 

MISE À JOUR 2:

Ceci est le code pour activer les boutons: Que dois-je tort? Je n'obtiens aucune erreur de liaison dans la console de sortie !?

private void DeleteDocument() 
     { 
      throw new NotImplementedException(); 
     } 

     private bool CanDeleteDocument() 
     { 
      return (IsSelected == true); 
     } 

     private void AddDocument() 
     { 

     } 

     private void OpenDocument() 
     { 

     } 

     public RelayCommand DeleteDocumentCommand 
     { 
      get { return _deleteDocumentCommand ?? (_deleteDocumentCommand = new RelayCommand(() => DeleteDocument(),() => CanDeleteDocument())); } 
     } 

     public RelayCommand AddDocumentCommand 
     { 
      get { return _addDocumentCommand ?? (_addDocumentCommand = new RelayCommand(() => AddDocument())); } 
     } 

     public RelayCommand OpenDocumentCommand 
     { 
      get { return _openDocumentCommand ?? (_openDocumentCommand = new RelayCommand(() => OpenDocument())); } 
     } 
+0

Vous devriez publier votre solution en guise de réponse. – svick

+0

J'ai mis à jour ma réponse, mais je ne sais pas à quel point ce sera utile. :-) –

Répondre

2

Est-ce le DocumentViewModelList une propriété de votre DocumentViewModel?

Typiquement, ce que je voudrais est un ViewModel pour cette fenêtre qui exposerait un ObservableCollection<T>T est ce que vous voulez afficher dans la liste. Ensuite, vous pouvez affecter le DataContext Window/Page/etc au ViewModel, puis lier le ItemsSource du ListBox à la propriété ObservableCollection<T>. Par exemple, voici un extrait de mon ViewModel. Par exemple, voici un extrait de mon ViewModel.

public class SomeViewModel 
{ 
    public ObservableCollection<SingleDocumentViewModel> Docs {get; private set; } 

    // other properties can go here 
} 

Dans le code-behind pour le XAML, (je le fais habituellement dans le constructeur), vous pouvez définir son DataContext à une nouvelle instance de votre jeu ViewModel

public AwesomeDocumentList() 
{ 
    this.DataContext = new SomeViewModel(); 
    // the rest of the constructor 
} 

Avec DataContext de la fenêtre , vous pouvez lier le ItemsSource à la propriété exposée (je l'ai appelé Docs)

<ListBox ItemsSource="{Binding Docs}" ... /> 

espoir qui aide.

Mise à jour

Dans le RelayCommand pour le bouton, avez-vous quelque chose de spécifié pour le prédicat CanExecute? Si non, alors je crois que le RelayCommand sera toujours activé par défaut. Mais si vous avez un prédicat spécifié, jetez un oeil là-dedans.

Le code que vous avez affiché pour la propriété IsSelected semble correct. On dirait que le problème est ailleurs.

+0

s'il vous plaît relire Eric, j'ai mis à jour la question :) – Elisabeth

+0

J'ai mis à jour le fil init Eric! – Elisabeth

+0

@Lisa La solution d'Eric est absolument correcte. Si vous avez tellement de mal à faire ce que vous voulez, il y a un problème dans la façon dont vous avez configuré ViewModel. Essayez simplifier tout et recommencer à zéro. Vous trouverez rapidement le problème. – NVM