Hi Boris,
if I understand you correctly you basically want to assign a different z-order to different subsets of your ink strokes. For that you would need one InkPresenter (or InkCanvas which is built on top of InkPresenter) for each layer of ink.
You go could down the route of creating your own control with multiple InkPresenters, but you might be able to accomplish what you want by layering a bunch on InkCanvas elements on top of each other.
As a starting point, here is a simple user control that can host ink and elements in different levels and allows you to move them between the levels:
XAML:
<UserControl x:Class="WindowsApplication1.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Canvas Name="mainCanvas"> <InkCanvas Name="lowerLayer" Width="{Binding ElementName=mainCanvas,Path=ActualWidth}" Height="{Binding ElementName=mainCanvas,Path=ActualHeight}" Background="Yellow" StrokeCollected="OnStroke" StrokeErasing="OnStrokeErasing"/> <InkCanvas Name="upperLayer" Width="{Binding ElementName=mainCanvas,Path=ActualWidth}" Height="{Binding ElementName=mainCanvas,Path=ActualHeight}" Background="Transparent" IsHitTestVisible="False" EditingMode="None" /> </Canvas> </UserControl>
C# code behind to manage the layers of ink and elements:
using System; using System.Collections.Generic; using System.Windows; using System.Windows.Ink; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media;
namespace WindowsApplication1 { public partial class UserControl1 : System.Windows.Controls.UserControl { private StrokeCollection _strokes = new StrokeCollection();
public UserControl1() { InitializeComponent(); }
private void OnStroke(object sender, InkCanvasStrokeCollectedEventArgs e) { _strokes.Add(e.Stroke); }
private void OnStrokeErasing(object sender, InkCanvasStrokeErasingEventArgs e) { _strokes.Remove(e.Stroke); }
public StrokeCollection Strokes { get { return _strokes; } }
public void AddElementBehindInk(UIElement element) { lowerLayer.Children.Add(element); }
public void AddElementOnTop(UIElement element) { upperLayer.Children.Add(element); }
public void MoveElementBehind(UIElement element) { if (upperLayer.Children.Contains(element)) { upperLayer.Children.Remove(element); lowerLayer.Children.Add(element); } }
public void MoveElementOnTop(UIElement element) { if (lowerLayer.Children.Contains(element)) { lowerLayer.Children.Remove(element); upperLayer.Children.Add(element); } }
public void MoveStrokeOnTop(Stroke stroke) { if (lowerLayer.Strokes.Contains(stroke)) { lowerLayer.Strokes.Remove(stroke); upperLayer.Strokes.Add(stroke); } }
public void MoveStrokeBehind(Stroke stroke) { if (upperLayer.Strokes.Contains(stroke)) { upperLayer.Strokes.Remove(stroke); lowerLayer.Strokes.Add(stroke); } } } }
Thanks, Stefan Wick
|