2016-05-16 2 views
0

J'ai cherché une réponse à mon problème, mais pas de chance jusqu'à maintenant. Je suis nouveau à MVVM mais je prends mes risques avec une application qui sera mise au travail.Navigation MVVM - L'instance d'affichage persiste bien que DataTemplate ait x: Shared = "False"

La navigation est implémentée par une commande de menu liée à une RelayCommand/Action réagissant au CommandParameter. Cela change le CurrentViewModel dans le MainWindowViewModel. MainWindow a un ContentControl avec son contenu lié au CurrentViewModel. Les vues appelées de cette manière sont toutes UserControls qui sont instanciées via DataTemplate.

<DataTemplate x:Shared="False" DataType="{x:Type vm:NewViewModel}"> 
    <local:NewView/> 
</DataTemplate> 

Lorsqu'une vue est appelée par le menu, elle fonctionne correctement. Cliquer à nouveau sur le même menu crée une nouvelle instance du viewmodel, mais la vue ne change pas (les anciennes valeurs sont toujours présentes). Il n'y a pas trop de messages à trouver sur ce problème car il semble ne pas partager l'instance de vue en mettant x: shared à false. Comme indiqué, cela ne fonctionne pas pour moi. J'ai également essayé setting the CurrentViewModel to null avant qu'il ne soit changé.

Il me manque probablement une solution évidente. Serait très bien pour l'aide quand même.

Voici le code: (le cas: "Correct" ne fonctionne pas)

private InvoiceViewModel _InvoiceViewModel = new InvoiceViewModel(); 
    private ProductsViewModel _ProductsViewModel = new ProductsViewModel(); 
    private PrintViewModel _PrintViewModel = new PrintViewModel(); 
    private CorrectInvoiceViewModel _CorrectInvoiceViewModel = new CorrectInvoiceViewModel(); 
    private RetouchInvoiceViewModel _RetouchInvoiceViewModel = new RetouchInvoiceViewModel(); 
    private CorrectionChainViewModel _CorrectionChainViewModel = new CorrectionChainViewModel(); 
    private RecipientsViewModel _RecipientsViewModel = new RecipientsViewModel(); 
    private AdjustmentsViewModel _AdjustmentsViewModel = new AdjustmentsViewModel(); 



    private ViewModelBase _CurrentViewModel; 
    public ViewModelBase CurrentViewModel { get { return _CurrentViewModel; } set { SetProperty(ref _CurrentViewModel, value);} } 

    private void OnMenuItemClick(string destination) 
    { 
     switch (destination) 
     { 
      case "Invoice": 
       CurrentViewModel = _InvoiceViewModel; 
       ViewModelTitle = "Neue Rechnung"; 
       break; 

      case "Products": 
       CurrentViewModel = _ProductsViewModel; 
       ViewModelTitle = "Produkte bearbeiten"; 
       break; 

      case "Correct": 
       { 
        CurrentViewModel = null; 
        CurrentViewModel = new CorrectInvoiceViewModel(); 

        ViewModelTitle = "Rechnungskorrektur"; 
        break; 
       } 
      case "Retouch": 
       { 
        CurrentViewModel = _RetouchInvoiceViewModel; 
        ViewModelTitle = "Retusche"; 
        break; 
       } 
      case "CorrectionChain": 
       { 
        CurrentViewModel = _CorrectionChainViewModel; 
        ViewModelTitle = "Rechnungsansicht und Korrekturreihe"; 
        break; 
       } 
      case "Recipients": 
       { 
        CurrentViewModel = _RecipientsViewModel; 
        ViewModelTitle = "Empfänger bearbeiten"; 
        break; 
       } 
      case "Adjustments": 
       { 
        CurrentViewModel = _AdjustmentsViewModel; 
        ViewModelTitle = "Adressfeld anpassen"; 
        break; 
       } 
      default: 
       CurrentViewModel = null; 
       break; 
     } 
    } 

et XAML:

<Controls:MetroWindow x:Name="wdw_Main" x:Class="PraxMat_View.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:PraxMat_View" 
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 
    xmlns:viewmod="clr-namespace:PraxMat_ViewModel;assembly=PraxMat_ViewModel" 
    DataContext="{StaticResource MainWindowViewModel_Resource}" 
    mc:Ignorable="d" 
    Title="PraxMat" Height="800" Width="1200" WindowTitleBrush="#FF2D2D30" TitleCaps="False" Icon="images/PraxMat_Logo.png" Background="Black" BorderBrush="{DynamicResource Grey04}" BorderThickness="1"> 
<Controls:MetroWindow.Resources> 
    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:InvoiceViewModel}"> 
     <local:InvoiceView/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:ProductsViewModel}"> 
     <local:ProductsView/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:PrintViewModel}"> 
     <local:PrintView/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:CorrectInvoiceViewModel}"> 
     <local:CorrectInvoiceView/> 
    </DataTemplate> 


    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:RetouchInvoiceViewModel}"> 
     <local:RetouchInvoiceView/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:CorrectionChainViewModel}"> 
     <local:CorrectionChainView DataContext="{StaticResource CorrectInvoiceViewModel_Resource}"/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:RecipientsViewModel}"> 
     <local:RecipientsView/> 
    </DataTemplate> 

    <DataTemplate x:Shared="False" DataType="{x:Type viewmod:AdjustmentsViewModel}"> 
     <local:AdjustmentsView/> 
    </DataTemplate> 


</Controls:MetroWindow.Resources> 
<Grid x:Name="grd_Main" Opacity="{Binding Opacity}"> 

    <Menu x:Name="men_Main" VerticalAlignment="Top" Height="30" Background="#FF1E1E1E" BorderBrush="{DynamicResource Grey07}" BorderThickness="0,0,0,1"> 

     <MenuItem Header="Menu" Background="{x:Null}" Foreground="{StaticResource Grey02}" Margin="26,3,0,0" Template="{DynamicResource DropShadowSubmenu}" Width="100" Padding="6,2,6,4"> 
      <MenuItem x:Name="mui_Invoice" Header="Neue Rechnung" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0" Command="{Binding MenuItemClick}" CommandParameter="Invoice" Margin="0,2,0,0"/> 
      <MenuItem x:Name="mui_AlterInvoice" Header="Rechnung anpassen" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu_PopupRight}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0"> 
       <MenuItem.ItemsPanel> 
        <ItemsPanelTemplate> 
         <StackPanel /> 
        </ItemsPanelTemplate> 
       </MenuItem.ItemsPanel> 
       <MenuItem x:Name="mui_CorrectInvoice" Header="Korrektur" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="0" Command="{Binding MenuItemClick}" CommandParameter="Correct" Margin="0,-4,0,0" /> 
       <MenuItem x:Name="mui_RetouchInvoice" Header="Retusche" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="0" Command="{Binding MenuItemClick}" CommandParameter="Retouch" /> 
       <MenuItem x:Name="mui_CorrectionChain" Header="Ansicht/Korrekturreihe" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="0" Command="{Binding MenuItemClick}" CommandParameter="CorrectionChain"/> 
      </MenuItem> 
      <MenuItem x:Name="mui_Payments" Header="Zahlungen" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0" Command="{Binding MenuItemClick}" CommandParameter="Payment"/> 

      <MenuItem Header="Diverses" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu_PopupRight}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0"> 
       <MenuItem.ItemsPanel> 
        <ItemsPanelTemplate> 
         <StackPanel /> 
        </ItemsPanelTemplate> 
       </MenuItem.ItemsPanel> 
       <MenuItem x:Name="mui_Products" Header="Produkte" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0" Command="{Binding MenuItemClick}" CommandParameter="Products" Margin="0,-4,0,0"/> 
       <MenuItem x:Name="mui_Recipients" Header="Empfänger" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0" Command="{Binding MenuItemClick}" CommandParameter="Recipients"/> 
       <MenuItem x:Name="mui_Adjustments" Header="Adressfeld" Background="#FF1E1E1E" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" BorderThickness="0" Width="150" Height="25" Padding="5,0,0,0" Command="{Binding MenuItemClick}" CommandParameter="Adjustments"/> 
      </MenuItem> 

     </MenuItem> 
     <MenuItem Header="{Binding ViewModelTitle}" Margin="60,3,0,0 " Padding="6,2,6,4" Background="{x:Null}" Foreground="{StaticResource Grey02}" Template="{DynamicResource DropShadowSubmenu}" IsEnabled="False" ></MenuItem> 
    </Menu> 


    <ScrollViewer Margin="0,30,0,0" Background="{DynamicResource Grey09}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> 

     <ContentControl Content="{Binding CurrentViewModel}" Background="#FF06B836"> 

     </ContentControl> 

    </ScrollViewer> 
</Grid> 

+0

On dirait que la vue que vous montrez a toujours le vieux viewmodel. Si vous créez une nouvelle instance de 'NewViewModel', vous êtes probablement en train de l'ignorer. Pouvons-nous voir tout le code C# qui devrait créer une nouvelle instance de 'NewViewModel', l'assigner à' CurrentViewModel', et tout le XAML qui devrait obtenir la nouvelle valeur de 'CurrentViewModel' dans du' Content' ou la propriété 'DataContext' quelque part? –

+0

Merci pour la réponse rapide. J'ai ajouté le code. J'ai vérifié que le constructeur du viewmodel est appelé. – user947737

+0

Avez-vous mis un point d'arrêt ici: 'CurrentViewModel = new CorrectInvoiceViewModel();' et confirmé que c'est la ligne de code qui est appelée lorsque vous exécutez la commande via l'élément de menu? –

Répondre

1

en attente de confirmation, mais après un certain temps dans le chat , il semble que le problème peut être ce bit dans CorrectInvoiceView.xaml

<UserControl.DataContext> 
    <StaticResource ResourceKey="CorrectInvoiceViewModel_Resource"/> 
</UserControl.DataContext> 

Votre DataTemplate pour CorrectInvoiceViewModel est correctement instancié lorsque CurrentViewModel devient CorrectInvoiceViewModel. Il est instancié avec la valeur CurrentViewModel pour un DataContext, puis remplace ce DataContext avec autre chose - une copie stockée de ce viewmodel, toujours la même copie stockée, car il est défini comme une ressource quelque part. Donc si vous supprimez ces trois lignes, je pense que vous devriez le voir se comporter comme prévu.

+0

Le problème a été résolu grâce à @Ed Plunkett, qui a eu la gentillesse de passer le temps nécessaire pour le résoudre! – user947737

+0

Pour tous ceux ayant le même problème: il est toujours nécessaire de définir le CurrentViewModel sur NULL avant de le réattribuer. – user947737

+0

@ user947737 Toute nouvelle valeur devrait faire le travail, je pense, mais bon, ça marche. –