### Install RichCanvas using NuGet Package Manager (C#) Source: https://github.com/mircea21s/richcanvas/wiki/Home-v2.4.2 This code snippet demonstrates how to install the RichCanvas package using the Package Manager Console in Visual Studio. It's a straightforward command for integrating the library into a .NET project. ```xml Install-Package RichCanvas ``` -------------------------------- ### XAML Basic Setup and ItemsSource Binding for RichCanvas Source: https://context7.com/mircea21s/richcanvas/llms.txt Demonstrates the basic XAML declaration for RichCanvas, including binding its ItemsSource to a ViewModel collection and configuring ItemContainerStyle for item properties like position and size. It also includes viewport manipulation binding and a custom converter. ```xml ``` -------------------------------- ### C# ViewModel for RichCanvas Item Management and Drawing Source: https://context7.com/mircea21s/richcanvas/llms.txt Provides a C# ViewModel example for RichCanvas, demonstrating how to manage an ObservableCollection of items and handle the DrawingEndedCommand. It shows how to add items programmatically and how the drawing state affects item creation. ```csharp public class CanvasViewModel : INotifyPropertyChanged { public ObservableCollection Items { get; } public ICommand OnDrawingEnded { get; } public CanvasViewModel() { Items = new ObservableCollection(); OnDrawingEnded = new RelayCommand(position => { // Called when user finishes drawing the item Console.WriteLine($"Item drawn at position: {position}"); }); } public void AddNewItem() { // When Top/Left/Width/Height are not set, user can draw with mouse Items.Add(new RectangleItem()); // When Top/Left are set but Width/Height are not, draw at position // Items.Add(new RectangleItem { Top = 100, Left = 100 }); // When all properties are set, item appears immediately // Items.Add(new RectangleItem { Top = 100, Left = 100, Width = 50, Height = 50 }); } } ``` -------------------------------- ### RichCanvas Snapping Configuration Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview Enables snapping behavior for items on the RichCanvas. When `EnableSnapping` is true, items will align to a grid based on the `GridSpacing` property after being drawn or dragged. This feature helps in precise placement and alignment of elements. ```XML ``` -------------------------------- ### Basic RichCanvas Integration in XAML Source: https://github.com/mircea21s/richcanvas/wiki/Home-v2.4.2 This XAML snippet shows the basic declaration of the RichItemsControl, enabling core canvas functionalities like panning, zooming, scrolling, and selection. It requires the RichCanvas namespace declaration. ```xml ``` -------------------------------- ### Custom RichCanvas State Implementation in C# Source: https://context7.com/mircea21s/richcanvas/llms.txt Demonstrates creating a custom canvas state by inheriting from 'CanvasState'. This allows overriding methods like 'Enter', 'Exit', and event handlers to implement unique behaviors for the canvas. ```csharp // Custom state example public class CustomCanvasState : CanvasState { public CustomCanvasState(RichCanvas canvas) : base(canvas) { } public override void Enter() { // Called when state is pushed onto stack Console.WriteLine("Custom state entered"); } public override void Exit() { // Called when state is popped from stack Console.WriteLine("Custom state exited"); } public override void HandleMouseDown(MouseButtonEventArgs e) { // Custom mouse down logic var position = e.GetPosition(Canvas.ItemsHost); Console.WriteLine($"Mouse down at: {position}"); } public override void HandleMouseMove(MouseEventArgs e) { // Custom mouse move logic } public override void HandleMouseUp(MouseButtonEventArgs e) { // Custom mouse up logic } } // Custom RichCanvas with default state override public class CustomRichCanvas : RichCanvas { public override CanvasState GetDefaultState() { return new CustomCanvasState(this); } } // Using custom canvas in XAML // // Programmatically pushing custom states public void ActivateCustomState(RichCanvas canvas) { var customState = new CustomCanvasState(canvas); canvas.PushState(customState); } ``` -------------------------------- ### MVVM Structure for RichCanvas with DataTemplates (XAML) Source: https://github.com/mircea21s/richcanvas/wiki/Home-v2.4.2 This XAML demonstrates a common structure for integrating RichCanvas within an MVVM pattern. It includes setting up the ItemsSource binding, defining DataTemplates for different item types (e.g., Rectangle), and configuring ItemContainerStyle for two-way data binding of position and size properties. ```xml ``` -------------------------------- ### RichCanvas Grid Background Drawing Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview Defines a grid background for RichCanvas using a `DrawingBrush`. The `GeometryDrawing` creates a rectangular grid pattern, and the `DrawingBrush` is configured to tile this pattern. It's crucial to bind the `Viewport` to `GridSpacing` and `Transform` to `AppliedTransform` for proper visual alignment with the canvas and snapping. ```XML ``` -------------------------------- ### Panning Gestures and Properties in RichCanvas Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview Panning in RichCanvas is typically initiated by holding the Space key and left-clicking. This behavior can be customized via the static RichCanvasGestures.Pan property. Programmatic control is available through the ViewportLocation dependency property. Automatic panning near viewport edges can be enabled with EnableAutoPanning, and its speed adjusted with AutoPanSpeed. ```csharp public static DependencyProperty ViewportLocationProperty = DependencyProperty.Register(...); public Point ViewportLocation { get => (Point)GetValue(ViewportLocationProperty); set => SetValue(ViewportLocationProperty, value); } ``` ```csharp public static DependencyProperty EnableAutoPanningProperty = DependencyProperty.Register(...); public bool EnableAutoPanning { get => (bool)GetValue(EnableAutoPanningProperty); set => SetValue(EnableAutoPanningProperty, value); } ``` ```csharp public static DependencyProperty AutoPanSpeedProperty = DependencyProperty.Register(...); public float AutoPanSpeed { get => (float)GetValue(AutoPanSpeedProperty); set => SetValue(AutoPanSpeedProperty, value); } ``` ```csharp public static string PanGesture = "Spacebar+Left Click"; // To change: RichCanvasGestures.Pan = "Ctrl+Left Click"; ``` -------------------------------- ### RichCanvas Zooming Operations (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt Provides C# code for programmatic zoom control within a RichCanvas component. It includes properties for zoom level, commands to zoom in, out, and reset, and a method to zoom to a specific point. Default gestures like CTRL + Mouse Wheel are also mentioned. ```csharp // Programmatic zoom control public class CanvasViewModel : INotifyPropertyChanged { private double _zoom = 1.0; public double Zoom { get => _zoom; set { _zoom = value; OnPropertyChanged(); } } // Zoom commands public ICommand ZoomInCommand => new RelayCommand(() => Zoom *= 1.2); public ICommand ZoomOutCommand => new RelayCommand(() => Zoom /= 1.2); public ICommand ResetZoomCommand => new RelayCommand(() => Zoom = 1.0); // Zoom to specific position programmatically public void ZoomToPoint(RichCanvas canvas, Point position, double scaleFactor) { canvas.ZoomAtPosition(position, scaleFactor); } } // Default gestures: // - CTRL + Mouse Wheel: Zoom in/out // - CTRL + Plus: Zoom in // - CTRL + Minus: Zoom out ``` -------------------------------- ### Bring Item into View with WPF Binding Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures RichCanvas to programmatically bring items into view using data binding. A 'ShouldBringIntoView' property on the item model is bound to a setter in the ItemContainerStyle. ```xml ``` -------------------------------- ### Implement ScalableItem Model and ViewModel for RichCanvas (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt Defines a ScalableItem model with Scale and AllowScaleChangeToUpdatePosition properties and a CanvasViewModel with methods for flipping items horizontally/vertically and setting custom scale. This supports scale manipulation and mirroring of items within RichCanvas. ```csharp // Item with scale control public class ScalableItem : DraggableItem { private Point _scale = new Point(1, 1); public Point Scale { get => _scale; set { _scale = value; OnPropertyChanged(); } } // AllowScaleChangeToUpdatePosition determines if Top/Left // adjust when scale is negative (flipped during drawing) private bool _allowScaleChangeToUpdatePosition = true; public bool AllowScaleChangeToUpdatePosition { get => _allowScaleChangeToUpdatePosition; set { _allowScaleChangeToUpdatePosition = value; OnPropertyChanged(); } } } // ViewModel operations public class CanvasViewModel { public void FlipItemHorizontally(ScalableItem item) { item.Scale = new Point(-item.Scale.X, item.Scale.Y); } public void FlipItemVertically(ScalableItem item) { item.Scale = new Point(item.Scale.X, -item.Scale.Y); } public void ScaleItem(ScalableItem item, double scaleX, double scaleY) { item.Scale = new Point(scaleX, scaleY); } } ``` -------------------------------- ### Basic RichCanvas XAML Declaration Source: https://github.com/mircea21s/richcanvas/wiki/Home This XAML snippet demonstrates how to declare the RichCanvas control in your WPF application. It requires the RichCanvas namespace to be defined and a background color set for hit-testing. ```xml ``` -------------------------------- ### Implement Draggable Items and Canvas ViewModel (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt This C# code defines a DraggableItem model with position properties and a CanvasViewModel for managing item movements. The DraggableItem implements INotifyPropertyChanged for UI updates. The CanvasViewModel provides methods to move individual items or multiple selected items, supporting both single-item and batched updates based on the RichCanvas configuration. ```csharp // Item model with position properties public class DraggableItem : INotifyPropertyChanged { private double _top; private double _left; private double _width = 50; private double _height = 50; public double Top { get => _top; set { _top = value; OnPropertyChanged(); } } public double Left { get => _left; set { _left = value; OnPropertyChanged(); } } public double Width { get => _width; set { _width = value; OnPropertyChanged(); } } public double Height { get => _height; set { _height = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } // Programmatically move items public class CanvasViewModel { public void MoveItem(DraggableItem item, double newTop, double newLeft) { item.Top = newTop; item.Left = newLeft; } public void MoveSelectedItems(double deltaX, double deltaY) { foreach (var item in SelectedItems.Cast()) // Assuming SelectedItems is accessible { item.Left += deltaX; item.Top += deltaY; } } } // RealTimeDraggingEnabled = false: Better performance, updates on drag completion // RealTimeDraggingEnabled = true: Live updates during drag ``` -------------------------------- ### Item Model and ViewModel for Focus Source: https://context7.com/mircea21s/richcanvas/llms.txt Defines an 'ViewableItem' model with a 'ShouldBringIntoView' property and a 'CanvasViewModel' with methods to trigger this property. This enables programmatic centering of items in the RichCanvas viewport. ```csharp // Item model public class ViewableItem : DraggableItem { private bool _shouldBringIntoView; public bool ShouldBringIntoView { get => _shouldBringIntoView; set { _shouldBringIntoView = value; OnPropertyChanged(); } } } // ViewModel operations public class CanvasViewModel { public void FocusOnItem(ViewableItem item) { // Setting this to true centers the item in viewport item.ShouldBringIntoView = true; } public void FocusOnFirstSelectedItem() { var item = SelectedItems.FirstOrDefault() as ViewableItem; if (item != null) { item.ShouldBringIntoView = true; } } } ``` -------------------------------- ### Drawing Items in RichCanvas Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview RichCanvas provides a default drawing mechanism for items added to its ItemsSource. The drawing behavior adapts based on whether item properties like Top, Left, Height, and Width are pre-defined or determined by user interaction (dragging). A DrawingEnded event and command are triggered after drawing is complete. ```xml ``` ```csharp public class DrawEndedEventArgs : RoutedEventArgs { public object DataContext { get; set; } public Point MousePosition { get; set; } } ``` ```csharp public static readonly RoutedEvent DrawingEndedEvent = EventManager.RegisterRoutedEvent( "DrawingEnded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RichCanvas)); public void OnDrawingEnded(DrawEndedEventArgs args) { // Handle drawing end event RaiseEvent(args); } ``` -------------------------------- ### RichCanvas Item Selection (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt Provides C# code for managing item selection within a RichCanvas component. It includes methods for programmatically selecting/clearing items, selecting all items, and selecting items within a specified rectangular area. Default gestures include drag selection and Ctrl+Click for multi-select. ```csharp // Selection management in ViewModel public class CanvasViewModel : INotifyPropertyChanged { public ObservableCollection Items { get; } public ObservableCollection SelectedItems { get; } private ItemModel _selectedItem; public ItemModel SelectedItem { get => _selectedItem; set { _selectedItem = value; OnPropertyChanged(); } } // Programmatically select items public void SelectItem(ItemModel item) { SelectedItems.Add(item); } public void ClearSelection() { SelectedItems.Clear(); } public void SelectAll() { SelectedItems.Clear(); foreach (var item in Items) SelectedItems.Add(item); } // Get elements in specific area public void SelectItemsInArea(RichCanvas canvas, Rect area) { var elementsInArea = canvas.GetElementsInArea(area); SelectedItems.Clear(); foreach (var element in elementsInArea) SelectedItems.Add((ItemModel)element); } } // Default selection gesture: Left mouse button drag creates selection rectangle // Click on item to select, Ctrl+Click for multi-select ``` -------------------------------- ### Enable Grid Snapping with Visual Grid in RichCanvas (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt This XAML configuration demonstrates how to enable grid snapping in RichCanvas and display a synchronized visual grid. The 'EnableSnapping' property must be set to 'True', and 'GridSpacing' defines the distance between grid lines. A DrawingBrush with a GeometryDrawing is used to render the grid lines as the background of the canvas. ```xml ``` -------------------------------- ### RichCanvas Event Handling in XAML Source: https://context7.com/mircea21s/richcanvas/llms.txt Defines event handlers for RichCanvas and its item containers directly in XAML. This approach links UI events like DrawingEnded and Zooming to specific methods in the code-behind. ```xml ``` -------------------------------- ### Manage Grid Snapping Properties in Canvas ViewModel (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt This C# code defines a CanvasViewModel that allows dynamic control over grid snapping properties. It includes properties for 'GridSpacing' and 'EnableSnapping', both implementing INotifyPropertyChanged for UI synchronization. It also exposes ICommand properties for toggling snapping and changing the grid size, enabling interactive adjustments to the canvas grid. ```csharp // ViewModel with dynamic grid spacing public class CanvasViewModel : INotifyPropertyChanged { private float _gridSpacing = 20f; private bool _enableSnapping = true; public float GridSpacing { get => _gridSpacing; set { _gridSpacing = value; OnPropertyChanged(); } } public bool EnableSnapping { get => _enableSnapping; set { _enableSnapping = value; OnPropertyChanged(); } } // Change grid size public ICommand SetGridSize10 => new RelayCommand(() => GridSpacing = 10); public ICommand SetGridSize20 => new RelayCommand(() => GridSpacing = 20); public ICommand SetGridSize50 => new RelayCommand(() => GridSpacing = 50); public ICommand ToggleSnapping => new RelayCommand(() => EnableSnapping = !EnableSnapping); public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } ``` -------------------------------- ### MVVM-compatible RichCanvas XAML Structure Source: https://github.com/mircea21s/richcanvas/wiki/Home This XAML structure shows how to integrate RichCanvas with the MVVM pattern. It binds the ItemsSource to your ViewModel's collection and configures ItemContainerStyle to manage item properties like position and size, with a visual trigger for selection. ```xml ``` -------------------------------- ### RichCanvas Item Selection Configuration Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview Configures single or multiple item selection in RichCanvas. Multiple selection is enabled by default. The `IsSelecting` property indicates an active selection, and `SelectionRectangle` provides the selection bounds. `SelectedItems` holds the currently selected items, which can also be set programmatically. `RealTimeSelectionEnabled` controls whether items are selected during rectangle resizing. ```XML ``` -------------------------------- ### Implement RotatableItem Model and ViewModel for RichCanvas (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt Provides the C# code for a RotatableItem model inheriting from DraggableItem and a CanvasViewModel class to manage item rotation. This enables dynamic angle updates for items within the RichCanvas. ```csharp // Item model with rotation public class RotatableItem : DraggableItem { private double _angle = 0; public double Angle { get => _angle; set { _angle = value; OnPropertyChanged(); } } } // ViewModel managing rotation public class CanvasViewModel { public void RotateSelectedItems(double angleDelta) { foreach (var item in SelectedItems.Cast()) { item.Angle = (item.Angle + angleDelta) % 360; } } public void SetItemRotation(RotatableItem item, double angle) { item.Angle = angle; } } // Note: ScaleTransform and TranslateTransform must be included // to maintain move and scale-while-drawing functionality ``` -------------------------------- ### Apply Custom RenderTransform to RichCanvasContainer Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvasContainer-Overview Demonstrates how to override the default RenderTransform of a RichCanvasContainer using the attached property 'rc:RichCanvasContainer.ApplyTransform'. It's crucial to include ScaleTransform and TranslateTransform if they are intended to be preserved for core functionalities like moving and scaling. ```xml ``` -------------------------------- ### RichCanvas Panning Operations (C#) Source: https://context7.com/mircea21s/richcanvas/llms.txt Provides C# code for programmatic viewport panning control in RichCanvas. It includes a property for the viewport location and methods to pan to a specific coordinate or center the view on an item. Auto-panning is mentioned as a feature activated by dragging near viewport edges. ```csharp // Programmatic viewport control public class CanvasViewModel : INotifyPropertyChanged { private Point _viewportLocation = new Point(0, 0); public Point ViewportLocation { get => _viewportLocation; set { _viewportLocation = value; OnPropertyChanged(); } } // Pan to specific location public void PanToLocation(double x, double y) { ViewportLocation = new Point(x, y); } // Center on specific item public void CenterOnItem(double itemLeft, double itemTop, Size viewportSize) { ViewportLocation = new Point( itemLeft - viewportSize.Width / 2, itemTop - viewportSize.Height / 2 ); } } // Default gesture: Space + Left Mouse Button to pan // Auto-panning activates when dragging/selecting near viewport edges ``` -------------------------------- ### XAML Item Drawing with Mouse and ViewModel Command Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures RichCanvas in XAML to enable automatic item drawing using mouse gestures. It binds the ItemsSource and specifies a DrawingEndedCommand to handle the completion of drawing an item, including a DataTemplate for rendering items. ```xml ``` -------------------------------- ### RichCanvas Item Selection (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures item selection behavior for RichCanvas using XAML attributes. It supports single and multiple item selection with two-way binding for SelectedItem and SelectedItems properties. Real-time selection can be enabled or disabled, and item container styles can be customized. ```xml ``` -------------------------------- ### RichCanvas Event Handling in C# Source: https://context7.com/mircea21s/richcanvas/llms.txt Implements the event handlers declared in XAML for RichCanvas and its item containers. These methods handle actions such as drawing completion, zooming, drag operations, and item selection/deselection. ```csharp // Code-behind event handlers private void OnDrawingEnded(object sender, RoutedEventArgs e) { var args = (DrawEndedEventArgs)e; Console.WriteLine($"Drawing ended at: {args.MousePosition}"); Console.WriteLine($"Item context: {args.ItemContext}"); } private void OnZooming(object sender, RoutedEventArgs e) { if (sender is RichCanvas canvas) { Console.WriteLine($"Current zoom: {canvas.ViewportZoom}"); } } private void OnDragStarted(object sender, DragStartedEventArgs e) { Console.WriteLine($"Drag started at: ({e.HorizontalOffset}, {e.VerticalOffset})"); } private void OnDragDelta(object sender, DragDeltaEventArgs e) { Console.WriteLine($"Drag delta: ({e.HorizontalChange}, {e.VerticalChange})"); } private void OnDragCompleted(object sender, DragCompletedEventArgs e) { Console.WriteLine($"Drag completed. Total: ({e.HorizontalChange}, {e.VerticalChange})"); } private void OnItemSelected(object sender, RoutedEventArgs e) { var container = (RichCanvasContainer)sender; Console.WriteLine($"Item selected: {container.DataContext}"); } private void OnItemUnselected(object sender, RoutedEventArgs e) { var container = (RichCanvasContainer)sender; Console.WriteLine($"Item unselected: {container.DataContext}"); } ``` -------------------------------- ### Customize RichCanvas Grid Style Source: https://github.com/mircea21s/richcanvas/wiki/ItemsControl-Overview Allows customization of the background grid's appearance. The 'GridStyle' property accepts a Drawing object. The default configuration uses an XML GeometryDrawing to define a red grid pattern. ```xml ``` -------------------------------- ### RichCanvas Panning Operations (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures panning behavior for RichCanvas using XAML attributes. It enables auto-panning with adjustable speed and tick rate, and supports two-way binding for the ViewportLocation property. The default gesture for panning is Space + Left Mouse Button. ```xml ``` -------------------------------- ### Apply Custom Transform to RichItemContainer (XAML) Source: https://github.com/mircea21s/richcanvas/wiki/ItemContainer-Overview Demonstrates how to apply a custom TransformGroup to a RichItemContainer using the ApplyTransform attached property in XAML. This allows for custom transformations like rotation in addition to the default scale and translation. Ensure ScaleTransform and TranslateTransform are included if move and scale functionalities are required. ```xml ``` -------------------------------- ### RichCanvas Zooming Operations (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures zooming behavior for RichCanvas using XAML attributes. It allows setting minimum and maximum scale limits, a scale factor for gesture-based zooming, and disabling zoom functionality. Two-way binding is supported for the ViewportZoom property. ```xml ``` -------------------------------- ### Control Container Scale and Flip Behavior in RichCanvas (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt Configures the ItemContainerStyle for RichCanvas to bind the Scale property and sets AllowScaleChangeToUpdatePosition to True. This allows for controlling the scale of containers and updating their position when scale changes, such as during flipping. ```xml ``` -------------------------------- ### Apply Custom Rotation Transform to Items in RichCanvas (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt Defines a DataTemplate for a RotatableItem in RichCanvas, applying a custom rotation transform while ensuring ScaleTransform and TranslateTransform are included to maintain dragging and drawing capabilities. ```xml ``` -------------------------------- ### Configure Item Dragging in RichCanvas (XAML) Source: https://context7.com/mircea21s/richcanvas/llms.txt This XAML snippet shows how to configure RichCanvas for item dragging. Setting 'RealTimeDraggingEnabled' to 'False' enables batched updates for better performance, while 'True' provides live updates during dragging. The 'IsDraggable' property on the item container style must be set to 'True' for items to be draggable. ```xml ``` -------------------------------- ### Customize RichCanvas Selection Rectangle Style Source: https://github.com/mircea21s/richcanvas/wiki/ItemsControl-Overview Enables modification of the selection rectangle's visual properties when using the selection feature. The 'SelectionRectangleStyle' property takes a Style object. The default style sets a dodger blue stroke and a semi-transparent dodger blue fill. ```xml ``` -------------------------------- ### Zooming Controls and Events in RichCanvas Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview Zooming in RichCanvas can be controlled via command bindings (CTRL + for zoom in, CTRL - for zoom out) or by holding CTRL and using the mouse wheel. The modifier key for mouse wheel zooming can be changed using RichCanvasGestures.ZoomModifierKey. Zooming can be disabled using DisableZoom, and programmatically adjusted via ViewportZoom within MinScale and MaxScale limits. The Zooming routed event is raised during zoom operations. ```csharp public static DependencyProperty ViewportZoomProperty = DependencyProperty.Register(...); public double ViewportZoom { get => (double)GetValue(ViewportZoomProperty); set => SetValue(ViewportZoomProperty, value); } ``` ```csharp public static DependencyProperty DisableZoomProperty = DependencyProperty.Register(...); public bool DisableZoom { get => (bool)GetValue(DisableZoomProperty); set => SetValue(DisableZoomProperty, value); } ``` ```csharp public static string ZoomInCommand = "CTRL+"; public static string ZoomOutCommand = "CTRL-"; public static string ZoomModifierKey = "CTRL"; ``` ```csharp public static readonly RoutedEvent ZoomingEvent = EventManager.RegisterRoutedEvent( "Zooming", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RichCanvas)); ``` -------------------------------- ### Enabling Scrolling with ScrollViewer in RichCanvas Source: https://github.com/mircea21s/richcanvas/wiki/RichCanvas-Overview To enable scrolling for the RichCanvas control, it needs to be placed inside a ScrollViewer. Properties like CanContentScroll, VerticalScrollBarVisibility, and HorizontalScrollBarVisibility on the ScrollViewer control its scrolling behavior. The sensitivity of scrolling within RichCanvas can be fine-tuned using the ScrollFactor dependency property. ```xml ``` ```csharp public static DependencyProperty ScrollFactorProperty = DependencyProperty.Register(...); public double ScrollFactor { get => (double)GetValue(ScrollFactorProperty); set => SetValue(ScrollFactorProperty, value); } ```