Чтобы решить эту проблему, мы должны сначала понять, почему эта проблема возникает.
ListView
имеет контейнер для повторного использования внутри, он не будет бесконечно создавать новые элементы списка, но будет перерабатывать.
В большинстве случаев такая переработка не является проблемой. Но это специально для InkCanvas
. InkCanvas
- это контроль состояния. Когда вы рисуете InkCanvas
, почерк сохраняется и отображается в пользовательском интерфейсе.
Если ваш элемент управления - TextBlock
, эта проблема не возникает, поскольку мы можем напрямую связать значение с TextBlock.Text
, но для инсульта InkCanvas
мы не можем напрямую связать, что вызовет так называемый остаток .
Поэтому, чтобы избежать этого, нам нужно очистить state
, то есть каждый раз, когда InkCanvas
создается или перезагружается, штрихи в InkCanvas
перерисовываются.
1. Создайте список для сохранения информации о ходе в ViewModel
public class ViewModel : INotifyPropertyChanged
{
// ... other code
public List<InkStroke> Strokes { get; set; }
public ViewModel()
{
Strokes = new List<InkStroke>();
}
}
2. Измените внутреннюю структуру CanvasControl
xaml
<Grid>
<InkCanvas x:Name="inkCanvas"
Margin="0 2"
MinWidth="1000"
MinHeight="300"
HorizontalAlignment="Stretch" >
</InkCanvas>
</Grid>
xaml.cs
public sealed partial class CanvasControl : UserControl
{
public CanvasControl()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
}
private void StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
if (Data != null)
{
var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes().ToList();
Data.Strokes = strokes.Select(p => p.Clone()).ToList();
}
}
public ViewModel Data
{
get { return (ViewModel)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(ViewModel), typeof(CanvasControl), new PropertyMetadata(null,new PropertyChangedCallback(Data_Changed)));
private static void Data_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(e.NewValue!=null && e.NewValue is ViewModel vm)
{
var strokes = vm.Strokes.Select(p=>p.Clone());
var instance = d as CanvasControl;
instance.inkCanvas.InkPresenter.StrokesCollected -= instance.StrokesCollected;
instance.inkCanvas.InkPresenter.StrokeContainer.Clear();
try
{
instance.inkCanvas.InkPresenter.StrokeContainer.AddStrokes(strokes);
}
catch (Exception)
{
}
instance.inkCanvas.InkPresenter.StrokesCollected += instance.StrokesCollected;
}
}
}
Таким образом, мы можем сохранить наши записи стабильными.