0

私のアプリケーションは、キャンバス上に多くの線とポリゴン/パスを表示します。ObservableCollections私のViewModelは、描画されるさまざまなアイテムを表す一連のを保持しています。

私が抱えている問題は、アプリケーションのズームとパンが非常に遅いことです。ズームとパンはすべて を使用してIvalueConverter処理され、ワー​​ルド座標系からキャンバス座標系に変換されます。

これを機能さ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、モデルで描画オブジェクトを作成および削除する必要があります。モデルが更新されるたびに、 my を更新する必要がありますdrawingVisual。しかし、正しい方法ではないモデルでビュー項目を作成しています。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>

my の監視可能なコレクションViewModel:

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

編集

ズームインおよびズームアウト ビューを使用したキャンバスのスクリーンショット:

ズームアウト:

ここに画像の説明を入力

画像は少し拡大縮小されていますが、実際には、拡大縮小しても線の太さ、ノード サイズ、矢印は一定のままです。ノードの投影座標のみが変更されます。

ズームイン:

ここに画像の説明を入力

4

1 に答える 1