1 year ago
#22286
j.j. Pita
WPF InkCanvas unable to Select items when using Touch and EditingMode is select and ParentControl.IsManipulationEnabled=True
My question is how to Select items in InkCanvas using Touch when the parent control and inkcanvas IsManipulationEnable = true.
I am experiencing an issue with InkCanvas that will not show the Select adorner and also unable to select item base on the following condition:
- ParentControl.IsManipulationEnable = true
- InkCanvas.EditingMode = InkCanvaseEditingMode.Select
- Using Touch
Also, I follow this example msdn, it also fails to select the items.
See below for reference on what is the issue:
- Using Mouse Mouse Select
- Using Touch Touch Select
Tried in .Net Framework 4.5 and in .Net 5 My Environment:
- Windows 10 Version 1909 (OS Build 18363.1556)
- With a Dell Touch Monitor SX2210T
Sample Code: XAML
<Window x:Class="InkCanvasSelect.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:InkCanvasSelect"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid x:Name="touchGrid"
ManipulationStarting="touchGrid_ManipulationStarting"
ManipulationDelta="touchGrid_ManipulationDelta"
ManipulationCompleted="touchGride_ManipulationCompleted">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding EditingMode}"
SelectedItem="{Binding SelectedInkCanvasEditingMode}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
FontSize="15"
Height="20" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<InkCanvas Background="AntiqueWhite"
x:Name="ink"
IsManipulationEnabled="True"
PreviewTouchDown="ink_PreviewTouchDown"
PreviewTouchUp="ink_PreviewTouchUp"
RenderTransform="{Binding ImageTransform}"
Grid.Row="1"/>
</Grid>
</Window>
CS
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
ImageTransform = new MatrixTransform();
EditingMode.Add(InkCanvasEditingMode.None);
EditingMode.Add(InkCanvasEditingMode.Ink);
EditingMode.Add(InkCanvasEditingMode.GestureOnly);
EditingMode.Add(InkCanvasEditingMode.InkAndGesture);
EditingMode.Add(InkCanvasEditingMode.EraseByPoint);
EditingMode.Add(InkCanvasEditingMode.EraseByStroke);
EditingMode.Add(InkCanvasEditingMode.Select);
}
private List<int> dec = new List<int>();
Point centerPoint;
private void ink_PreviewTouchDown(object sender, TouchEventArgs e)
{
dec.Add(e.TouchDevice.Id);
if (dec.Count == 1)
{
TouchPoint touchPoint = e.GetTouchPoint(ink);
centerPoint = touchPoint.Position;
}
if (dec.Count > 1)
{
if (ink.EditingMode != InkCanvasEditingMode.None)
{
ink.EditingMode = InkCanvasEditingMode.None;
}
}
}
private void ink_PreviewTouchUp(object sender, TouchEventArgs e)
{
if (dec.Count > 1)
{
if (ink.EditingMode == InkCanvasEditingMode.None)
{
ink.EditingMode = InkCanvasEditingMode.Ink;
}
}
dec.Remove(e.TouchDevice.Id);
}
private void touchGrid_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
e.ManipulationContainer = ink;
e.Mode = ManipulationModes.All;
}
private void touchGrid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
//
if (dec.Count < 2) return;
// two fingers to achieve zoom
if (dec.Count == 2)
{
foreach (Stroke stroke in ink.Strokes)
{
Matrix matrix = new Matrix();
matrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y, centerPoint.X, centerPoint.Y);
stroke.Transform(matrix, false);
}
}
//three fingers to achieve move
else if (dec.Count == 3)
{
foreach (Stroke stroke in ink.Strokes)
{
Matrix matrix = new Matrix();
matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
stroke.Transform(matrix, false);
}
}
//other achieve rotate
else
{
ink.ManipulationDelta += InkCanvas_ManipulationDelta;
}
}
private void touchGride_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
//TODO some thing completed
}
private MatrixTransform imageTransform;
public MatrixTransform ImageTransform
{
get { return imageTransform; }
set
{
if (value != imageTransform)
{
imageTransform = value;
RaisePropertyChanged("ImageTransform");
}
}
}
private List<InkCanvasEditingMode> editingMode = new List<InkCanvasEditingMode>();
public List<InkCanvasEditingMode> EditingMode
{
get { return editingMode; }
set
{
if (value != editingMode)
{
editingMode = value;
RaisePropertyChanged("EditingMode");
}
}
}
private InkCanvasEditingMode selectedInkCanvasEditingMode;
public InkCanvasEditingMode SelectedInkCanvasEditingMode
{
get { return selectedInkCanvasEditingMode; }
set
{
if (value != selectedInkCanvasEditingMode)
{
ink.EditingMode= selectedInkCanvasEditingMode = value;
RaisePropertyChanged("SelectedInkCanvasEditingMode");
}
}
}
private void InkCanvas_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
// Ask for manipulations to be reported relative to the canvas
e.ManipulationContainer = touchGrid;
}
private void InkCanvas_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
ManipulationDelta md = e.DeltaManipulation;
Vector trans = md.Translation;
double rotate = md.Rotation;
Matrix m = imageTransform.Matrix;
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = m.Transform(center);
// Update matrix to reflect translation/rotation
m.Translate(trans.X, trans.Y);
m.RotateAt(rotate, center.X, center.Y);
imageTransform.Matrix = m;
RaisePropertyChanged("ImageTransform");
e.Handled = true;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
Solution that worked for me The work around that I found.
- For the Grid ManipulationCompleted and ManipulationDelta eventHandler
cancelled the manipulation if 1 touch point
- referred to the comment in this link by "flipMarch 26, 2012 at 11:32 AM"
flipMarch 26, 2012 at 11:32 AM There is another (and probably better) solution to this problem. Using the ManipulationCompletedEventArgs e.Cancel() function. This will cancel the manipulation and sends finger inputs as mouse events. >private void ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) if (e.TotalManipulation.Translation.X == 0 && e.TotalManipulation.Translation.Y == 0) { e.Cancel(); }
private void touchGrid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
if (dec.Count <= 1)
{
e.Cancel();
return;
}
// rest of the code
}
private void touchGride_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
if (dec.Count <= 1)
{
e.Cancel();
}
//TODO some thing completed
}
.net
wpf
touch
inkcanvas
0 Answers
Your Answer