MVVM导航 - 虽然DataTemplate具有x:Shared =“False”,但视图实例仍然存在

时间:2016-05-16 17:58:08

标签: c# wpf mvvm

我一直在寻找我的问题的答案,但到目前为止没有运气。 我是MVVM的新手,但我正在利用一个可以投入使用的应用程序。

导航由绑定到对CommandParameter作出反应的RelayCommand / Action的Menu-Command实现。这将切换MainWindowViewModel中的CurrentViewModel。 MainWindow有一个ContentControl,其内容绑定到CurrentViewModel。以这种方式调用的视图都是通过DataTemplate实例化的UserControl。

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

当菜单调出视图时,它可以正常工作。再次单击相同的菜单会创建视图模型的新实例,但视图不会更改(旧值仍然存在)。 没有太多关于此问题的帖子,因为它似乎取决于不通过将x:shared设置为false来共享视图实例。如上所述,这对我不起作用。我也试过setting the CurrentViewModel to null 在改变之前。

我可能错过了一个明显的解决方案。无论如何都会很乐意提供帮助。

以下是代码:(案例:“正确”无效)

    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;
        }
    }

和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>

1 个答案:

答案 0 :(得分:1)

等待确认,但在聊天一段时间后,看起来问题可能是CorrectInvoiceView.xaml中的这个问题

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

DataTemplate更改为CorrectInvoiceViewModel时,CurrentViewModel CorrectInvoiceViewModel CurrentViewModel被正确实例化了。它使用DataContext的值|进行实例化,然后用其他东西替换该DataContext - 该视图模型的存储副本,始终是相同的存储副本,因为它被定义为某个地方的资源。

因此,如果您删除这三行,我认为您应该看到它按预期运行。