繁体   English   中英

是一种基于 ObservableCollection 实现 DrawingVisual 的 MVVM WPF 方式吗

[英]Is the a MVVM WPF way to implement DrawingVisual based on an ObservableCollection

我的应用程序在 canvas 上显示了很多线和多边形/路径。 我的 ViewModel 包含一系列ObservableCollections代表要绘制的不同项目。

我遇到的问题是应用程序的缩放和平移速度非常慢。 缩放和平移都使用IvalueConverter ,并将世界坐标系转换为 canvas 坐标系。

为此,我必须NotifyPropertyChange屏幕上可见的所有对象,以强制使用最新的平移和缩放值重新绘制它们。 它适用于几百行,但对于数千行它非常慢。 而且,如果您缩小以使所有对象都可见,因此受到NotifyPropertyChange的影响,它几乎无法使用超过 10,000 行。

我没有以任何方式使用多边形内置功能,因为所有处理、选择移动等都在视图模型中处理。 因此,我想尝试使用DrawingVisual而不是Shapes ,因为我知道它们的开销要低得多,但我找不到任何好的 MVVM 示例来说明如何使用它们。 我看到的示例表明它们是在代码隐藏中构建的,这不是我认为我应该使用它们的方式。

示例如下:

//new DrawingVisual
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
drawingContext.Close();

//creating a Host as follows:
public MyVisualHost()
    {
    _children = new VisualCollection(this);
    _children.Add(CreateDrawingVisualRectangle());
    _children.Add(CreateDrawingVisualText());
    _children.Add(CreateDrawingVisualEllipses());

   this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
    }

除非有 WPF 方法可以使用DrawingVisual绑定到我的可观察集合,否则我需要在我的模型中创建和删除绘图对象。 每次更新 model 时,它都必须更新我的drawingVisual 但后来我在 model 中创建查看项目,这不是正确的方法。 谁能建议我应该如何在我的 MVVM 应用程序中实现DrawingVisual而不是Shapes

这是我目前使用的使用Shapes的代码的摘录

XAML

    <ItemsControl x:Name="Catchments">
        <ItemsControl.Resources>
            <CollectionViewSource x:Key="CatchmentPolygons" Source="{Binding Path=NetworkMain.Catchments}"></CollectionViewSource>
            <DataTemplate DataType="{x:Type cad:Catchment}">
                <Polygon 
                    Stroke="{Binding IsSelected, Mode=OneWay, Converter={StaticResource ObjectColour}, ConverterParameter=Catchment}"
                    StrokeThickness="1" 
                    Visibility="{Binding Visible, Mode=OneWay, TargetNullValue='Hidden'}"
                    Points="{Binding Points, Mode=OneWay, Converter={StaticResource CollectionPointConverter}}">
                    <Polygon.Fill>
                        <SolidColorBrush 
                            Color="{Binding IsSelected, Mode=OneWay, Converter={StaticResource ObjectColour}, ConverterParameter=Catchment}" 
                            Opacity=".25"
                            >
                            
                        </SolidColorBrush>
                    </Polygon.Fill>
                </Polygon>
            </DataTemplate>
        </ItemsControl.Resources>
        <ItemsControl.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Source={StaticResource CatchmentPolygons}}"></CollectionContainer>
            </CompositeCollection>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas 
                    ClipToBounds="true">
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

我的ViewModel中的可观察到的 Collections :

    public ObservableCollection<Conduit> Conduits { get; set; } = new();
    public ObservableCollection<Node> Nodes { get; set; } = new();
    public ObservableCollection<Catchment> Catchments { get; set; } = new();

编辑

Canvas 的屏幕截图,带有放大和缩小视图:

缩小:

在此处输入图像描述

图像已经缩放了一点,但实际上,当您放大和缩小时,线条粗细、节点大小和箭头保持不变。 只有节点的投影坐标发生变化。

放大:

在此处输入图像描述

您可以将依赖项属性添加到您的可视主机并将其绑定到视图 model 的源属性。

然后视觉宿主可以为源集合中的每个项目创建一个DrawingVisual

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM