为什么我的 WPF 应用程序首次启动时显示 ViewModel 的类名而不是其内容(属性)?

问题描述 投票:0回答:2

我将 MainWindowViewModel 绑定到 MainWindow 的 DataContext。 然后我将这个 MainWindowViewModel 初始化为特定的 itemsPageViewModel

问题是在启动时我看到 itemsPageViewModel 的类名而不是其内容: Startup

但是,通过按钮(RelayCommands)切换页面后,同一个 ViewModel 现在显示其内容: PageSwitched

两个操作都通过相同的代码行:

CurrentPageViewModel = _itemsPageViewModel

如何产生不同的结果?

代码

MainWindow.xaml

 <Window x:Class="ListItemUI.Views.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"
        mc:Ignorable="d"
        Title="ListItemUI" Height="400" Width="600">
    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="10"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <Grid Grid.Row="0">
                <StackPanel Orientation="Horizontal">
                    <Button Content="ITEMS" Margin="2" Command ="{Binding SelectItemsPageViewModel}"></Button>
                    <Button Content="HELP" Margin="2" Command ="{Binding SelectInfoPageViewModel}"></Button>
                </StackPanel>
            </Grid>

            <ContentControl Grid.Row="2" Content="{Binding CurrentPageViewModel}"/>

    </Grid>
 </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
using ListItemUI.InfoPage.ViewModels;
using ListItemUI.ListItemPage.ViewModels;
using ListItemUI.ViewModels;

namespace ListItemUI.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow(IPageFactory itemPageFactory, IPageFactory infoPageFactory)
        {
            InitializeComponent();
            var mainWindowVM = new MainWindowViewModel(itemPageFactory,infoPageFactory);
            DataContext = mainWindowVM;
        }
    }
}

MainWindowViewModel.cs

using System;
using System.Windows.Input;
using ListItemUI.ListItemPage.ViewModels;

namespace ListItemUI.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        private readonly IListItemUIViewModel _itemsPageViewModel;
        private readonly IListItemUIViewModel _infoPageViewModel;
        public ICommand SelectItemsPageViewModel { get; }
        public ICommand SelectInfoPageViewModel { get; }


        public object CurrentPageViewModel
        {
            get { return _currentPageViewModel; }
            set
            {
                _currentPageViewModel = value;
                 RaisePropertyChanged(() => CurrentPageViewModel);
            }
        }
        private object _currentPageViewModel;


        public MainWindowViewModel(IPageFactory itemsPageFactory, IPageFactory infoPageFactory)
        {
            _itemsPageViewModel = itemsPageFactory.CreatePage();
            _infoPageViewModel = infoPageFactory.CreatePage();


            SelectItemsPageViewModel = new RelayCommand(_ =>
            {
                    CurrentPageViewModel = _itemsPageViewModel;

            });

            SelectInfoPageViewModel = new RelayCommand(_ =>
            {
                CurrentPageViewModel = _infoPageViewModel;
            });

            CurrentPageViewModel = _itemsPageViewModel;


        }

    }
}

ListItemPage.xaml(数据模板)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:viewModels ="clr-namespace:ListItemUI.ListItemPage.ViewModels">

    <DataTemplate DataType="{x:Type viewModels:ItemViewModel}">
        <StackPanel>
            <TextBlock Foreground="RoyalBlue" FontWeight="Bold" Text="{Binding Path=ItemViewDescription, StringFormat='Group Info = {0}'}"></TextBlock>
        </StackPanel>
    </DataTemplate>

    <DataTemplate DataType="{x:Type viewModels:ItemsPageViewModel}">
        <StackPanel>
            <TextBlock Text ="{Binding Path=Title}"></TextBlock>
            <Grid Grid.Column="0" Background="Aquamarine">
            <ListBox ItemsSource="{Binding Path=LocalItemViewModels}" Margin="5">
            </ListBox>
        </Grid>
        </StackPanel>
    </DataTemplate>
</ResourceDictionary>

App.xaml

<Application x:Class="ListItemUI.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>

         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>
                 <ResourceDictionary Source="ListItemPage/Views/ListItemPage.xaml"></ResourceDictionary>
                 <ResourceDictionary Source="InfoPage/Views/InfoView.xaml"></ResourceDictionary>
                 <!--GLOBAL RESOURCES -->
                 <ResourceDictionary Source="Views/GlobalResources.xaml"></ResourceDictionary>
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>
    </Application.Resources>
</Application>
c# wpf xaml mvvm viewmodel
2个回答
2
投票

我们使用了一种解决方法来解决这个特定问题。 我们选择不使用资源字典,将 viewModel 的 dataTemplates 直接放入 mainwindow.xaml 中:现在一切正常。 当我们使用资源字典时,会发生一些奇怪的事情。


0
投票

尽管这个问题提出已经有几年了,但我也遇到了类似的问题。我在 App.xaml 中声明了我的 DataType,如下所示:

<Application.Resources>

    <DataTemplate DataType="{x:Type TypeName=vm:DeviceViewViewModel}">
        <view:DeviceView />
    </DataTemplate>

</Application.Resources>

无论我如何尝试,我的视图都无法正确显示。只有类型/类名称 Fusion.UI.Wpf.MVVM.Views.DeviceView.xaml 以文本字符串形式显示在我的主窗口的左上角。

当我将上述代码移至 MainWindow.xaml 代码时,一切正常。对我来说真的很奇怪,我可以补充一点,我一直在使用这种方法,即在我的 App.xaml 中声明数据类型,所以我在这里完全被震撼了,不知道为什么它突然不起作用,或者我缺少什么。

© www.soinside.com 2019 - 2024. All rights reserved.