我将 MainWindowViewModel 绑定到 MainWindow 的 DataContext。 然后我将这个 MainWindowViewModel 初始化为特定的 itemsPageViewModel。
问题是在启动时我看到 itemsPageViewModel 的类名而不是其内容:
但是,通过按钮(RelayCommands)切换页面后,同一个 ViewModel 现在显示其内容:
两个操作都通过相同的代码行:
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>
我们使用了一种解决方法来解决这个特定问题。 我们选择不使用资源字典,将 viewModel 的 dataTemplates 直接放入 mainwindow.xaml 中:现在一切正常。 当我们使用资源字典时,会发生一些奇怪的事情。
尽管这个问题提出已经有几年了,但我也遇到了类似的问题。我在 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 中声明数据类型,所以我在这里完全被震撼了,不知道为什么它突然不起作用,或者我缺少什么。