私のアプリケーションは、キャンバス上に多くの線とポリゴン/パスを表示します。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();
編集
ズームインおよびズームアウト ビューを使用したキャンバスのスクリーンショット:
ズームアウト:
画像は少し拡大縮小されていますが、実際には、拡大縮小しても線の太さ、ノード サイズ、矢印は一定のままです。ノードの投影座標のみが変更されます。
ズームイン: