【发布时间】:2012-07-16 07:25:32
【问题描述】:
我需要创建一个简单的菜单/选择设计工具 - 想法是选择类别和更多选择,这些选择由所选类别过滤。最终这将在 Kiosk 风格的环境中运行。
我正在使用 MVVM,我的设计包含一个视图,其中包含两个 ItemsControl 内的 2 个网格 - 一个用于类别(2 行 x 10 列),一个用于选择(10 x 10)。在我的 ViewModel 中,这些 ItemsControl 都绑定到 ObservableCollection 对象,其中一些细节(标题、颜色等)绑定到部件的属性。 DataTemplate 绑定到单独程序集中的项目类,因为我也想在 kiosk 应用程序中重用它们。
我使用“ModifiedBehaviours”类将我的网格对象上的左右点击映射到 ViewModel 拾取的命令,类似于此
How can I attach two attached behaviors to one XAML element?
从我读过的内容来看,该设计似乎“干净”(此处对 MVVM 而言相对较新),因为视图的代码隐藏除了将 ViewModel 分配给窗口的 DataContext 之外,没有任何内容,没有 x:name= 标记视图和 ViewModel 不直接与视图交互。
但是我确实遇到了性能问题。
当用户单击一个类别时,我会创建一个新的 ObservableCollection,其中包含它的详细信息 - 我还在设计模式下填写空白,因此我最终有 100 个选项,其中的空白选项具有“右键单击编辑”他们。
创建这个集合的时间很短——在 1.6 Ghz 上网本上
我尝试了各种方法。 首先,我通过删除一些渐变和其他内容来简化我的 XAML,以使其尽可能简单 - 最终归结为单个文本块。 然后在刷新集合时,我单独创建它,然后将其分配给绑定的集合,以便更新“一次”发生。 第三,我稍微打破了我的设计,并在窗口和网格的更新代码周围添加了 BeginInit() 和 EndInit()。
这些都没有丝毫改善。
以下内容 - 这导致了我的问题。
- 我从项目控件中删除了其中一个命令行为 - 我需要同时进行右击和左击。这必须将每个项目单元格(其中 100 个)的事件绑定到命令的事实是否会导致问题?
对于每个网格单元格是否有另一种方法来左右单击?
两者分别产生了影响,两者共同使性能“可以接受” - 但仍然非常缓慢。还有什么我可以看的吗?
我的控件看起来像这样(在单独的程序集中)。在任何人如上所述指出之前,我已经尝试删除很多内容,甚至将其删除为只是一个文本块。
<Control.Resources>
<Style x:Key="MyBorderStyle" TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="3"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="False">
<Setter Property="BorderBrush" Value="{Binding BackColour}"/>
<Setter Property="BorderThickness" Value="0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Control.Resources>
<Grid>
<Border Margin="1" Style="{StaticResource MyBorderStyle}" CornerRadius="8">
<CommandBehaviour:CommandBehaviorCollection.Behaviors>
<CommandBehaviour:BehaviorBinding Event="MouseLeftButtonDown" Command="{Binding DataContext.SelectLeftCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding ItemKey}"/>
<CommandBehaviour:BehaviorBinding Event="MouseRightButtonDown" Command="{Binding DataContext.SelectRightCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding ItemKey}"/>
</CommandBehaviour:CommandBehaviorCollection.Behaviors>
<Border.Background>
<LinearGradientBrush StartPoint="0.7,0" EndPoint="0.7,1">
<GradientStop Color="{Binding BackColour}" Offset="0"/>
<GradientStop Color="#33333333" Offset="1.5"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{Binding ForeColour}" Text="{Binding Description}"/>
</Border>
</Grid>
当我将它复制到主窗口中的 ItemsTemplate 时,我可以保留很多内容,并且性能改进持续存在。
声明-咆哮 WPF 的最大问题之一似乎是许多性能(和其他)问题都在某个地方“陷入困境” - 在幕后的代码中 - 这使得在没有外部和有时非常复杂的性能和分析工具以及下载、安装和学习它们的时间。
真的是裤子。
然后呼吸... 声明结束-咆哮
【问题讨论】:
-
您是否尝试过重新设计以使您无需在绑定中使用
RelativeSource?