dum*_*dad 7 wpf mvvm wpf-controls mvvm-light
我正在使用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>
Run Code Online (Sandbox Code Playgroud)
我想交换中心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...}" />
Run Code Online (Sandbox Code Playgroud)
当我在Expression Blend中设计UserControl时,这将非常有用,因为定位器可以为ViewModel提供虚拟数据.但是在运行时会发生什么 如何通过主ViewModel中的集合提供的UserControl的ViewModel类实例覆盖该绑定?在设计时MainWindow也会出现同样的问题.如果我在Expression Blend中使用MainWindow的外观,那么该绑定如何被设计时主ViewModel中的集合提供的UserControl的ViewModel类实例覆盖?
有许多问题和答案已经触及:
在/sf/answers/233434631/中, akjoshi建议主ViewModel保存UserControl的ViewModel实例; 但是当我设计UserControl本身时,它是如何工作的?
在/sf/answers/693720891/中, tam指出"你想让你的datacontext保持打开并可用于绑定到你正在使用这个控件的控件",并在下面的评论SoMoS补充说,需要一个"在ViewModel中为绑定属性创建属性,当有人想要更改控件的一个属性时(比如启用了一些子控件),他必须通过View Model".这是有希望的,但我不知道该怎么做代替MainViewModel的可绑定的UserControlViewModel集合.
在/sf/answers/443846791/中, Ehsan Ershadi建议"对于UserControles使用MVVM Light ViewModelLocator不是一个好主意,因为它是一个静态属性,当你要实例化你的用户控件的多个实例时将会有相同的常见ViewModel,所以它们都是相同的,如果您决定在整个项目中使用它一次,这不是我们想要的UserControl." 然后声明"要解决这个问题,你需要通过使所有属性非静态来修改ViewModelLocator".我不确定这对我有什么帮助.
在/sf/answers/184648131/之后的评论中,Jon Mitchell提到"看起来MVVM看起来并不适合创建用户控件".我希望这不对.
相比之下,在何时应该使用UserControl而不是Page?dthrasher提到"许多WPF MVVM框架似乎都避免使用NavigationWindow和Page控件来支持使用嵌套的UserControls组合页面",即UserControls是MVVM中的普通设备.
在/sf/answers/125905461/中, Reed Copsey提醒沙箱"UserControls总是可以通过暴露属性和使用DataBinding与其控件进行通信.这非常好,因为它在所有方面都保留了MVVM样式. " 并且"包含控件可以使用属性将两个用户控件上的两个属性链接在一起,同样保留干净的边界"但是当我在Expression Blend中设计UserControl时,我再也看不出这有什么帮助.
在我应该使用用户控件我的意见,而不是的DataTemplates?Rachel在将代码剪切并粘贴到DataTemplate之前偶尔提到使用Expression Blend来设计UserControl:"如果我想用它来设计DataTemplate,我通常会创建一个新的UserControl,按照我想要的方式设计它,然后将内容复制/粘贴到DataTemplate中"
对这篇文章长度问题感到抱歉!我很困惑如何在设计一个UserControl时使用MVVM Light,注定是MainWindow上集合中项目的可视化,特别是如何设置三个绑定:运行时视图模型,主要设计时间视图模型窗口及其用户控件的实例化,以及用户控件的设计时间视图模型.
我觉得你过于复杂了:
有什么不对:
<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>
<MyShinyUserControl DataContext={Binding}/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Run Code Online (Sandbox Code Playgroud)
将每个VibeEvent绑定到用户控件的DataContext.在用户控件本身,我建议创建一个设计时DataContext,以使设计更容易.Design-Time DataContext看起来像这样:
<UserControl x:Class="EMC.Windows.AlarmsModule.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:AlarmsModule="clr-namespace:EMC.Windows.AlarmsModule" d:DesignHeight="300"
d:DesignWidth="300"
d:DataContext="{d:DesignInstance Type=AlarmsModule:Alarm}"
>
Run Code Online (Sandbox Code Playgroud)
这将使您进入可以构建用户控件并在其中包含设计时数据的位置.它很简单,并且不需要太多(如果有的话)脚手架.
| 归档时间: |
|
| 查看次数: |
4658 次 |
| 最近记录: |