2010-05-21 4 views
3

J'ai un DataGrid avec la mise en œuvre de maître détail comme suit:passage de données à la fenêtre des enfants dans Silverlight 4 en utilisant MVVM

<data:DataGrid x:Name="dgData" Width="600" ItemsSource="{Binding Path=ItemCollection}" 
         HorizontalScrollBarVisibility="Hidden" CanUserSortColumns="False" RowDetailsVisibilityChanged="dgData_RowDetailsVisibilityChanged"> 
        <data:DataGrid.Columns> 
         <data:DataGridTextColumn Header="Item" Width="*" Binding="{Binding Item,Mode=TwoWay}"/> 
         <data:DataGridTextColumn Header="Company" Width="*" Binding="{Binding Company,Mode=TwoWay}"/> 

        </data:DataGrid.Columns> 
        <data:DataGrid.RowDetailsTemplate> 
         <DataTemplate> 
          <data:DataGrid x:Name="dgrdRowDetail" Width="400" AutoGenerateColumns="False" HorizontalAlignment="Center" 
             HorizontalScrollBarVisibility="Hidden" Grid.Row="1"> 
           <data:DataGrid.Columns> 
            <data:DataGridTextColumn Header="Date" Width="*" Binding="{Binding Date,Mode=TwoWay}"/> 
            <data:DataGridTextColumn Header="Price" Width="*" Binding="{Binding Price, Mode=TwoWay}"/> 
            <data:DataGridTemplateColumn> 
             <data:DataGridTemplateColumn.CellTemplate> 
              <DataTemplate> 
               <Button Content="Show More Details" Click="buttonShowDetail_Click"></Button> 
              </DataTemplate> 
             </data:DataGridTemplateColumn.CellTemplate> 
            </data:DataGridTemplateColumn> 
           </data:DataGrid.Columns> 
          </data:DataGrid> 
         </DataTemplate> 
        </data:DataGrid.RowDetailsTemplate> 
       </data:DataGrid> 

Je veux ouvrir une fenêtre enfant en cliquant sur le bouton qui affiche plus de détails sur le produit. J'utilise le modèle MVVM.

Mon modèle contient une méthode qui prend le nom de l'élément en entrée et retransmet les données de détails.

Mon problème est comment dois-je passer l'élément à ViewModel qui obtiendra les données de détails du modèle? et où shoukd j'ouvre la nouvelle fenêtre enfant? Dans View ou ViewModel?

S'il vous plaît help.Thanks.

Répondre

5

L'ouverture de la fenêtre enfant à partir d'un modèle de vue enfreint la séparation entre la vue et le modèle de vue dont le motif est censé être entièrement composé. Donc, vous n'avez probablement pas beaucoup de choix sur l'endroit où vous ouvrez la fenêtre enfant à partir du code derrière la page sur laquelle se trouve la grille. (Et cela viole le modèle aussi, mais, à moins d'une solution compliquée, c'est à peu près tout ce que vous pouvez faire.) J'utilise le modèle MVVM, mais je ne suis pas "religieux" à ce sujet. Je vais violer certains préceptes du modèle lorsque l'efficacité le dicte.

En ce qui concerne la transmission de l'élément au ViewModel, je suppose que vous pouvez créer une propriété sur ViewModel qui représente un identifiant pour l'élément. J'ai utilisé des fenêtres enfants comme formulaires de saisie de données pour la mise à jour et l'ajout. J'ai tendance à créer un ViewModel pour chacun d'entre eux. Dans votre cas, vous disposez d'un ViewModel qui représente les détails de l'élément. Il y aurait une sorte d'identification liée à l'article et les détails. Ce serait une propriété publique sur ViewModel. Vous pouvez créer un constructeur pour la fenêtre enfant qui prend cet ID en tant que paramètre. Ensuite, le constructeur de fenêtre enfant pourrait créer le ViewModel et lui envoyer l'ID.

Quelque chose comme ceci - où DomainEdit est le nom de la fenêtre enfant.

public DomainEdit() 
    { 
     InitializeComponent(); 

     devm = new DomainEditVM(); 
     DataContext = devm; 
    } 

    public DomainEdit(Guid domainId) : this() 
    { 
     devm.DomainId = domainId; 
     devm.GetDomain(); 
     txtTitle.Text = "Edit Domain"; 
    } 

Puis, à partir du code derrière où le bouton clic pour la grille se produit, vous créez la fenêtre enfant avec le nouveau constructeur, en passant l'ID que vous obtenez de l'élément de liaison dans la ligne de la grille, et une vue indépendante modèle pour la fenêtre de l'enfant prend le relais.

Au moins, c'est ce qui a fonctionné pour moi.

+0

Avez-vous vraiment besoin d'utiliser Guid comme Id d'une entité? Soyez prudent en utilisant Guid lorsque vous avez des tonnes d'entités, cela consomme beaucoup d'espace dans votre base de données. Pour 99% des cas, int ou long est très bien. – andrecarlucci

+0

L'exemple ci-dessus était un extrait abrégé de code provenant de quelque chose sur lequel je travaillais sur un site client. Je n'ai pas eu le choix quant à l'utilisation de Guids pour les identifiants. Cela faisait partie de la conception de la base de données quand je suis arrivé là. Je suis d'accord que int ou long serait mieux, mais en raison des contraintes du système, nous devions utiliser Guids. – Chazmanian

0

Le motif médiateur (service de messagerie entre les vues concernant notre application composite) fait le travail. En outre, déléguez la création de la vue détaillée dans un service de fenêtre enfant et transmettez l'objet sélectionné via le service de messagerie. Ensuite, vous n'obtiendrez aucune violation de modèle.

Questions connexes