2010-05-25 8 views
0

J'ai un contrôle utilisateur personnalisé basé sur un contrôle Grid. J'ai un ViewModel qui expose cela comme une propriété. Je voudrais que le XAML sur la vue se lie à cela. Je suis sûr que cela doit être facile mais je suis assez nouveau pour WPF. Comment cela est-il réalisé?WPF XAML Bind Grid

Un grand merci à l'avance

(sous la direction d'ajouter plus d'info)

Exemple de vue sans lier à ViewModel. Notez que j'ai une grille personnalisée qui contient un certain nombre de panneaux de pile personnalisés qui contient un certain nombre de contrôles de contenu à en-tête personnalisé. Ceux-ci sont déterminés pendant le chargement de ViewModel.

<MyCustomGrid:CustomGrid> 
    <MyCustomGrid:CustomStackPanel> 
     <MyCustomGrid:CustomHeaderedContentControl/> 
    </MyCustomGrid:CustomStackPanel> 
    <MyCustomGrid:CustomStackPanel> 
     <MyCustomGrid:CustomHeaderedContentControl/> 
    </MyCustomGrid:CustomStackPanel> 
</MyCustomGrid:CustomGrid> 

ViewModel contient simplement une liste qui contient une liste, etc. Notez que la CustomGrid est une liste car il peut y avoir plus d'un, mais un seul sera lié avec une propriété spécifique.

+2

Il existe plusieurs façons de le faire en fonction de la configuration. Pourriez-vous poster du code sur la façon dont votre contrôle utilisateur et viewmodel ressemble? Il sera beaucoup plus simple d'expliquer une réponse lorsque le scénario de la question est plus concret. – ThomasAndersson

+0

J'ai mis à jour le poste, merci. –

Répondre

0

étapes de base

  1. Régler le DataContext du contrôle de l'utilisateur (ou le contrôle/fenêtre contenant votre contrôle utilisateur) à une instance de type de modèle, avec une propriété de données qui est un ObservableCollection<SomeDataType>. Lier le ItemSourceListView à la propriété Data. Lier la propriété DisplayMemberBinding de GridViewColumn aux propriétés de SomeDataType.

Ainsi vous avez quelque chose comme ceci:

<ListView SelectionMode="Single" 
      HorizontalAlignment="Stretch" 
      ItemsSource="{Binding Data}"> 
    <ListView.View> 
     <GridView > 
      <GridViewColumn Header="Name of Prop2" 
          DisplayMemberBinding="{Binding Path=Prop1}" /> 
      <GridViewColumn Header="Name of Prop2" 
          DisplayMemberBinding="{Binding Path=Prop2}" /> 
      <GridViewColumn Header="Name of Prop3" 
          DisplayMemberBinding="{Binding Path=Prop3}" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

Vous pouvez lier à d'autres types, et avoir le contrôle sur la mise en forme, etc., mais c'est le cas simple.

+0

Cela ne me donne pas tout à fait ce que je veux. La grille, les panneaux de pile qu'il doit présenter et le contenu à afficher dans ces panneaux sont instanciés dans le modèle de vue lorsque le modèle de vue est instancié. Je veux juste présenter cela dans la vue. Désolé si je ne l'explique pas très bien. –

+0

@JonArchway: les contrôles WPF se lient aux propriétés du contrôle DataContext du contrôle. Vous devez donc vous assurer que vous avez défini 'DataContext' sur quelque chose avec les propriétés appropriées et que ces propriétés sont remplies. Cela aiderait si vous incluiez quelque chose de la structure à laquelle vous essayez de vous lier (je soupçonne qu'il vous manque quelque chose d'évident - une fois que cela a été souligné). – Richard

+0

OK, donc si je fais cela dans le codebehind je peux tout ajouter en faisant quelque chose comme SomeGridOnTheXamlView.Children.Add (viewModel.MyCustomGrid). Je veux faire quelque chose comme ça directement dans le XAML? Je suis évidemment très stupide ici, alors n'hésitez pas à signaler ma stupidité! :-) –

0

Je suis toujours pas sûr exactement ce que vous voulez atteindre, mais je vais avoir un aller quand même et peut-être nous pouvons itérer à une solution à partir de là.

A en juger par votre code XAML ci-dessus, vous avez plusieurs contrôles personnalisés. Vous avez mentionné que le niveau supérieur est basé sur Grid. Est-ce que Grid est dans le contrôle, ou en tant que ItemPanelTemplate pour un ItemsControl? J'ai l'impression que vous voulez que les données lient le contenu de votre viewmodel, et pour cela vous devez baser vos contrôles personnalisés sur ItemsControl. Corrigez-moi si je me trompe.

Quelque chose comme ça (comme mentionded, ceci suppose MyCustomGrid comme ItemsControl:

<UserControl Name="MyCustomGrid"> 
      <ItemsControl ItemsSource="{Binding Path=MyStackPanelsCollection}"> 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <Grid IsItemsHost="True" /> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemContainerStyle> 
        <Style TargetType="{x:Type MyCustomGrid:MyCustomStackPanel}"> 
         <Setter Property="Grid.Row" Value="{Binding Path=GridRow}" /> 
         <Setter Property="Grid.Column" Value="{Binding Path=GridColumn}" /> 
        </Style> 
       </ItemsControl.ItemContainerStyle> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate DataType="{x:Type MyCustomGrid:MyCustomStackPanelViewModel}"> 
         <ContentPresenter Content="{Binding Path=MySerializedObjectTurnedInToControl}" /> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
     </UserControl> 

Si ce n'est pas le cas, comme dans vous liez votre CustomStackPanel etc directement à une propriété nommée dans votre viewmodel, il pourrait ressembler à:.

<MyCustomGrid:CustomGrid DataContext="{Binding Path=ViewModel}"> 
    <MyCustomGrid:CustomStackPanel DataContext="{Binding Path=MyFirstStackPanelViewModel}"> 

...

Désolé si je comprends mal encore, je pourrais très bien être manque quelque chose évidente

+0

Je pense que le problème que j'ai est que le CustomStackPanel n'est pas connu lors de la création de la vue dans le XAML. Le nombre de CustomStackPanels n'est connu qu'après le chargement. La même chose avec le contenu de ces panneaux de pile. Ce que je n'explique pas très bien, c'est que le contenu de ces contrôles est essentiellement chargé à partir d'un fichier. Ce fichier contient un modèle d'objet sérialisé qui représente ce qui doit être chargé. Je voulais simplement dire si cela a du sens? –

+0

Cela rend les choses un peu plus claires en effet. Je pense toujours à une solution basée sur ItemsControl et DataTemplates pour vos objets sérialisés personnalisés. Je vais éditer mon post avec un exemple. – ThomasAndersson