2010-04-01 4 views
2

J'ai les suivantes ItemsControl dans Silverlight 3.MVVM Reliure dans Silverlight3 ItemsControl pour obtenir le contrôle parent DataContext

<ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 

      <Button x:Name="MyBtn" Height="40" Content="{Binding Name}" 
       Tag="{Binding Value}" 
       cmd:ButtonBaseExtensions.Command="{Binding ElementName=LayoutRoot, Path=ButtonCommand}" 
       cmd:ButtonBaseExtensions.CommandParameter="{Binding ElementName=MyBtn, Path=Tag}"/> 

     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Le problème est que je ItemsControl lié à la collection dans mon ViewModel, mais je dois la bouton pour déclencher une commande sur le ViewModel qui n'est bien sûr pas disponible dans le DataContext du bouton puisqu'il ne contient que la collection.

Je peux activer la commande en définissant mon ViewModel en tant que ressource, puis en le liant en tant que StaticResource, mais je veux savoir pourquoi la liaison de l'élément à l'élément ne fonctionnera pas dans ce scénario. Je préférerais ne pas utiliser la liaison StaticResource, car cela nécessite le constructeur par défaut sur le ViewModel et donc je ne peux pas injecter mes données facilement.

MISE À JOUR

Je travaille lentement à travers cette ... En regardant les suggestions de Peter je réalisais que je peux avoir des problèmes de liaison plus graves en raison de ma mise en page. J'ai deux barrages routiers possibles, mais d'abord les choses d'abord.

Mes éléments contrôle ci-dessus est enveloppé dans un autre contrôle éléments qui est lié à une collection observable. J'ai déplacé le contrôle de mes objets afin que ce soit un enfant direct du contrôle des objets racine. Il a été enveloppé dans un autre contrôle que je vais obtenir. J'ai donc essayé l'élément de liaison au contrôle d'éléments ControlItemList, mais c'est une collection donc il ne peut pas trouver ma méthode ButtonCommand dans cette collection. Ce que je dois faire est de lier à un élément de cette collection. Comment puis-je lier un seul élément de la collection?

<Grid x:Name="LayoutRoot" Background="White"><!-- DataContext="{Binding Path=., Source={StaticResource lvvm}}">--> 
    <StackPanel Orientation="Vertical"> 
     <ItemsControl x:Name="ControlItemList" ItemsSource="{Binding}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition MinWidth="100" /> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
         <TextBlock x:Name="ControlName" Grid.Column="0" Text="{Binding Name}" VerticalAlignment="Center" /> 
         <ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 

Ainsi, en supposant que je peux obtenir ce qui précède pour travailler l'autre bloc de route est que mes articles de contrôle est enveloppé dans un autre usercontrol que j'utilise pour obtenir DataTemplateSelector fonctionnalité de type. Je pense que ce contrôle peut m'empêcher d'accéder au DataContext parent. Y a-t-il une limite quant à la hauteur de l'arbre que vous pouvez atteindre?

<common:DeviceControlTemplateSelector Grid.Column="1" FieldType="{Binding ValueType}" Margin="0,2,0,2"> 
          <common:DeviceControlTemplateSelector.StringTemplate> 
           <DataTemplate> 
            <TextBox Text="{Binding Value, Mode=TwoWay}" Width="100"/> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.StringTemplate> 
          <common:DeviceControlTemplateSelector.DateTimeTemplate> 
           <DataTemplate> 
            <TextBox Text="this is date time binding" Width="100"/> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.DateTimeTemplate> 
          <common:DeviceControlTemplateSelector.BooleanTemplate> 
           <DataTemplate> 
            <CheckBox IsChecked="{Binding Value, Mode=TwoWay}" /> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.BooleanTemplate> 
          <common:DeviceControlTemplateSelector.IntegerTemplate> 
           <DataTemplate> 
            <ComboBox ItemsSource="{Binding ValueCollection}" DisplayMemberPath="Value" SelectedIndex="{Binding Value, Mode=TwoWay}" > 

            </ComboBox> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.IntegerTemplate> 
          <common:DeviceControlTemplateSelector.MultiButtonTemplate> 
           <DataTemplate> 
             <ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
              <ItemsControl.ItemTemplate> 
               <DataTemplate> 

                <Button x:Name="MyBtn" 
                  Height="40" Content="{Binding Name}" 
                  Tag="{Binding Value}" 
                  cmd:ButtonBaseExtensions.Command="{Binding ElementName=ControlItemList, Path=DataContext.ButtonCommand}"                
                  cmd:ButtonBaseExtensions.CommandParameter="{Binding Value}"/> 
               </DataTemplate> 
              </ItemsControl.ItemTemplate> 
             </ItemsControl> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.MultiButtonTemplate> 

            <Button x:Name="MyBtn" 
                  Height="40" Content="{Binding Name}" 
                  Tag="{Binding Value}" 
                  cmd:ButtonBaseExtensions.Command="{Binding ElementName=ControlItemList, Path=ButtonCommand}"                
                  cmd:ButtonBaseExtensions.CommandParameter="{Binding Value}"/> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 

Merci encore à tous pour votre aide!

Répondre

0

La messagerie MVVM est un concept fort pour la communication entre ViewModels. Vous pouvez utiliser PRISM Eventaggregator ou la classe Messenger de MVVM Light Toolkit. Sur la commande button, vous pouvez publier un message et vous y abonner dans le viewmodel.

+0

Merci silverfighter pour le poste, mais je voudrais vraiment comprendre pourquoi mon code ne fonctionne pas au-dessus. Je devrais peut-être aller sur la route de messagerie ou rendre le ViewModel staticresource, mais je ne comprends pas pourquoi je ne peux pas accéder au datacontext d'objets parent depuis mon itemscontrol. – BigTundra

+0

L'EventAggregator est-il trop puissant pour la messagerie dans un seul ViewModel (et encore moins dans le Module)? – Pat

1

Essayez de changer
de

cmd: ButtonBaseExtensions.Command = "{Binding ElementName = LayoutRoot, Path = ButtonCommand}"

à

cmd: ButtonBaseExtensions.Command = "{Binding ElementName = LayoutRoot, Path = DataContext.ButtonCommand} »

OU

cmd: ButtonBaseExtensions.Command = "{Liaison ElementName = LayoutRoot.DataContext, Path = ButtonCommand}"

+0

Je ne suis pas capable de faire fonctionner cela parce que le DataContext de LayoutRoot est un ObservableCollection, donc quand j'essaye de lier à ma méthode ButtonCommand je reçois ... System.Windows.Data Erreur: Erreur de BindingExpression path: 'ButtonCommand' propriété introuvable sur 'System.Collections.ObjectModel.ObservableCollection'1 [Chopper.Common.DeviceControlViewModel]' 'System.Collections.ObjectModel.ObservableCollection'1 [Chopper.Common.DeviceControlViewModel]' (HashCode = 26753075). BindingExpression: Path = 'DataContext.ButtonCommand' DataItem = 'System.Windows.Controls.ItemsControl' Comment puis-je lier à l'élément? – BigTundra

Questions connexes