我正在使用MVVM Light和WPF编写一些数据可视化代码。以下是一个片段:
<Window x:Class="EventBlockVisualization.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:ignore="http://www.ignore.com"
Title="MainWindow"
mc:Ignorable="d ignore"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ItemsPanelTemplate x:Key="GraphRowItemsPanelTemplate">
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Window.Resources>
<Grid IsSharedSizeScope="True">
<ScrollViewer Margin="8" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
<ItemsControl x:Name="GraphItemsControl" Margin="8" ItemsSource="{Binding VibeEvents, Mode=OneTime}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="NameWidthSizeGroup" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="NameTextBlock" Text="{Binding Name}" Grid.Column="0" Margin="4,0"/>
<ItemsControl x:Name="GraphRowItemsControl" ItemsSource="{Binding VibeEventViewModels, Mode=OneTime}" ItemsPanel="{DynamicResource GraphRowItemsPanelTemplate}" Grid.Column="1" Margin="4,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Center" Height="10">
<TextBlock x:Name="FGTitleTextBox" Text="{Binding FGTitle}" Visibility="Collapsed"/>
<Button Margin="1,0,0,0" Width="{Binding LengthInSeconds}" HorizontalAlignment="Left" Background="{Binding BackgroundColor}" BorderBrush="#FF2186A1">
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock FontWeight="Bold" Text="{Binding FGTitle}"/>
<TextBlock Text="{Binding LengthText}"/>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
我想替换中央的
ItemsControl.ItemTemplate
DataTemplate
,并将其更改为用户控件,以便我可以在Expression Blend中更轻松地设计它。我找不到包含MVVM Light中用户控件的简单示例,但有一些教程文章。例如,在MVVM实例化方法(选项6)中,Paul Stovell建议在MVVM Light中绑定UserControl的ViewModel,如下所示:
<UserControl ...>
<UserControl.Resources>
<ViewModelLocator x:Key="ViewModelLocator"/>
</UserControl.Resources>
<TextBox Text="{Binding Source={DynamicResource ViewModelLocator}, Path=CalculatorViewModel...}" />
当我在Expression Blend中设计UserControl时,这将非常有效,因为定位器可以提供一个带有虚拟数据的ViewModel。但是,在运行时会发生什么呢?该绑定如何被覆盖为由主ViewModel中的集合提供的UserControl的ViewModel类的实例?在设计时间的MainWindow上也会出现同样的问题。如果我正在Expression Blend中处理MainWindow的外观和感觉,那么该绑定如何被覆盖为由设计时主ViewModel中的集合提供的UserControl的ViewModel类的实例?已经有一些关于这个问题的问题和答案。
在https://dev59.com/qXA75IYBdhLWcg3wW3y8#3334780中,akjoshi建议主ViewModel持有UserControl的ViewModel实例;但是当我设计UserControl本身时,这该如何实现呢?
在https://dev59.com/dmLVa4cB1Zd3GeqPsw8K#9910298中,tam指出,“您希望保持数据上下文开放并可用于绑定到使用此控件的控件中”,并在以下评论中,SoMoS补充说,需要“在ViewModel中为绑定属性创建属性,并且当有人想要更改控件的一个属性(例如某个子控件启用)时,他将不得不通过View Model”。这很有前途,但我不确定在MainViewModel的可绑定集合中应该做什么。
在https://dev59.com/2ljUa4cB1Zd3GeqPOy74#6340668中,Ehsan Ershadi建议,“不建议使用MVVM Light ViewModelLocator来创建UserControles,因为它是静态属性,当您要实例化多个用户控件的实例时,它们都将具有相同的公共ViewModel,因此它们都会以相同的方式运作,而这不是我们希望在整个项目中使用一次的UserControl中看到的情况。”然后指出,“要解决这个问题,您需要通过使所有属性非静态来修改ViewModelLocator,例如”。我不确定这对我有什么帮助。
在https://dev59.com/f3E85IYBdhLWcg3wvGER#2637830的评论中,Jon Mitchell提到,“MVVM似乎并不是创建用户控件的理想选择”。我希望这不是正确的。
相反,在何时应该使用UserControl而不是Page?中,dthrasher提到,“许多WPF MVVM框架似乎避免使用NavigationWindow和Page控件,而是使用嵌套UserControls组合页面”,即UserControls是MVVM中常见的设备。
在https://dev59.com/R3I-5IYBdhLWcg3wipBk#1798649中,Reed Copsey提醒sandbox,“UserControls始终可以通过公开属性并使用DataBinding与其包含的控件交流。这非常好,因为它在所有方面都保留了MVVM风格。”并且“包含的控件可以使用属性将两个用户控件上的两个属性链接在一起,从而保留了清晰的边界”。但是当我在Expression Blend设计UserControl时,我仍然不知道如何实现这一点。
在我应该使用UserControls来代替DataTemplates作为我的视图吗?中,Rachel提到偶尔使用Expression Blend来设计UserControl,然后将代码复制粘贴到DataTemplate中:“如果我确实想要将其用于设计DataTemplate,我通常会创建一个新的UserControl,按照自己的方式进行设计,然后将内容复制/粘贴到DataTemplate中”
抱歉这个问题有点长!我对如何在设计一个UserControl以成为MainWindow中集合项的可视化方式使用MVVM Light感到困惑,特别是如何设置三个绑定:运行时视图模型,主窗口和其实例的设计时视图模型以及UserControl独立的设计时视图模型。
d:DataContext
并不是它(我认为),尽管看起来很直观。 - dumbledadd:DataContext
是将视图模型绑定到用户控件的数据上下文的预期方式。再次感谢。 - dumbledad