为一组类似的用户控件

时间:2017-02-07 11:52:55

标签: wpf user-controls wpf-controls

在我的项目中,我必须使用WPF在Canvas对象上放置一大组类似的用户控件(大约2000)。基本上,它只是一组可以改变可见性的矩形,可以选择并存储数据对象。

我在附加属性的帮助下添加了新的控件,如下所示:

    public static readonly DependencyProperty VisualStaticBlocksProperty =
        DependencyProperty.RegisterAttached("VisualStaticBlocks", typeof(ObservableCollection<VisualBlockViewModel>), typeof(BindableBlocksBehaviour), 
        new UIPropertyMetadata(null, VisualStaticBlocksPropertyChanged));

    private static void VisualStaticBlocksPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        ClickSightView clickSight = source as ClickSightView;
        ObservableCollection<VisualBlockViewModel> visualBlocks = e.NewValue as ObservableCollection<VisualBlockViewModel>;
        if (clickSight != null && visualBlocks != null)
        {
            foreach (VisualBlockViewModel visualBlock in visualBlocks)
            {
                clickSight.StaticBlocksCanvas.Children.Add(new VisualBlockView(visualBlock));
            }
        }
    }

然而,构建所有这些(大约2秒)需要花费大量时间。我使用分析器检查主要问题是在LoadBaml()方法中,在InitializeComponent()方法中调用。

据我所知,LoadBaml()用于解析xaml标记。是否有可能以某种方式缓存组件的LoadBaml()结果并在每次创建新控件实例时重用它而不是解析xaml?

修改  为了直观地表示这组对象,我已经在其上创建了Canvas的用户控件,并创建了附加属性 VisualStaticBlocks 以将blockblock视图模型(类型 VisualBlockViewModel )添加到此控件并插入视觉阻止实例(直接输入 VisualBlockView )到Canvas。

EDIT2: 我完全放弃了使用用户控件来解决这个问题。 由于我的控件非常简单,我使用了Rectangle()类,而是使用了3个手动添加的绑定和3个手动添加的事件。当然,根本没有InitializeComponent()调用。它允许我在200毫秒内构建2000个矩形的集合,这快10倍。 无论如何,如果我每次都可以克隆类似的对象而不加载BAML,那么仍​​然会感激信息。

1 个答案:

答案 0 :(得分:1)

听起来你创建视觉元素所花费的时间有问题。我可以看到为什么你认为你需要调用InitializeComponent,但这不是WPF的工作方式。

作为noted here

  

对InitializeComponent()的调用(通常在至少Window和UserControl的默认构造函数中调用)实际上是对控件的partial类的方法调用(而不是按照我的预期调用对象层次结构) )。

这让我怀疑你不明白InitializeComponent如何(或为什么)有效;不可能一次调用它来构建多个元素,而不是外部。

您正在使用ObservableCollection,它既不适用于大型数据集也不适用于复杂视图。考虑使用线程安全的ObservableCollection并在后台线程上添加数据对象。这应该不是问题,因为您要添加数据对象(视图模型)与可视对象(视图);可视对象应添加到创建它们的同一个线程(UI)上。

如果您没有解释如何直观地表示这些对象,那将有助于提供其他信息。集合是否绑定到ItemsControl,是否定义了DataTemplate以直观地表示每个数据对象?