Mürekkep Silme Örneği
Bu uygulama, mürekkep vuruşlarının silinmesini gösteren Mürekkep Koleksiyonu Örneği üzerine inşa edilmiştir. Örnek, kullanıcıya dört farklı mod içeren bir menü sağlar: mürekkep etkinliği, köşelerde silme, kesişim noktalarında silme ve vuruşları silme.
Mürekkep etkin modda, InkCollector nesnesi Mürekkep Koleksiyonu Örneği'nde gösterildiği gibi mürekkep toplar.
Silme modunda, kullanıcının imleçle dokunduğu mevcut mürekkep vuruşlarının kesimleri silinir. Ayrıca, uç noktalar veya kesişimler kırmızı bir daire ile işaretlenebilir.
Bu örneğin en ilginç bölümleri, InkErase
formunun OnPaint
olay işleyicisinde ve formun OnMouseMove
olay işleyicisinden çağrılan silme işlevlerinde bulunur.
Dönerek Cusplar ve Kesişimler Üzerinde Dolaşma
Formun OnPaint
olay işleyicisi önce çizgileri boyar ve uygulama moduna bağlı olarak, küçük kırmızı bir daire ile tüm uç noktalarını veya kesişimleri bulabilir ve işaretleyebilir. Bir tepe noktası, bir çizginin ani bir şekilde yön değiştirdiği noktayı işaretler. Kesişim, bir vuruşun kendisiyle veya başka bir vuruşla kesiştiği bir noktayı işaretler.
Paint olayı, bir denetim yeniden çizildiğinde gerçekleşir.
Not
Örnek, formun Refresh yöntemini kullanarak bir çizgi silindiğinde veya uygulama modu değiştiğinde formun kendisini yeniden çizmesini zorlar.
private void InkErase_OnPaint(object sender, PaintEventArgs e)
{
Strokes strokesToPaint = myInkCollector.Ink.Strokes;
myInkCollector.Renderer.Draw(e.Graphics, strokesToPaint);
switch (mode)
{
case ApplicationMode.CuspErase:
PaintCusps(e.Graphics, strokesToPaint);
break;
case ApplicationMode.IntersectErase:
PaintIntersections(e.Graphics, strokesToPaint);
break;
}
}
PaintCusps
içinde, kod her vuruştaki her bir cusp içinde yinelenir ve etrafına kırmızı bir daire çizer. Vuruşun PolylineCusps özelliği, bir stok içindeki noktaların cusps'a karşılık gelen dizinlerini döndürür. Ayrıca, noktayı DrawEllipse yöntemiyle ilgili koordinatlara dönüştüren oluşturucu nesnesinin InkSpaceToPixel yöntemine de dikkat edin.
private void PaintCusps(Graphics g, Strokes strokesToPaint)
{
foreach (Stroke currentStroke in strokesToPaint)
{
int[] cusps = currentStroke.PolylineCusps;
foreach (int i in cusps)
{
Point pt = currentStroke.GetPoint(i);
// Convert the X, Y position to Window based pixel coordinates
myInkCollector.Renderer.InkSpaceToPixel(g, ref pt);
// Draw a red circle as the cusp position
g.DrawEllipse(Pens.Red, pt.X-3, pt.Y-3, 6, 6);
}
}
}
PaintIntersections
içinde kod, tüm vuruş kümesiyle kesişimlerini bulmak için her vuruşta yinelenir. Vuruşun FindIntersections yöntemine Strokes koleksiyonu geçirildiğini ve kesişimleri temsil eden kayan nokta dizin değerleri dizisi döndürdüğünü unutmayın. Kod daha sonra her kesişim için bir X-Y koordinatı hesaplar ve etrafına kırmızı bir daire çizer.
private void PaintIntersections(Graphics g, Strokes strokesToPaint)
{
foreach (Stroke currentStroke in strokesToPaint)
{
float[] intersections = currentStroke.FindIntersections(strokesToPaint);
}
}
İki Ucu Olan Bir Kalemi İşleme
CursorDown, NewPacketsve Stroke olayları için InkCollector nesnesi için üç olay işleyicisi tanımlanır. Her olay işleyicisi, kalemin hangi ucunun kullanıldığını görmek için İmleci nesnesinin Ters özelliğini denetler. Kalem ters çevrildiğinde:
-
myInkCollector_CursorDown
yöntemi, vuruşu saydam hale getirir. -
myInkCollector_NewPackets
yöntemi vuruşları siler. -
myInkCollector_Stroke
yöntemi olayı iptal eder. NewPackets olayları, Stroke olayından önce oluşturulur.
İmleci İzleme
Kullanıcının kalem veya fare kullanıp kullanmadığı MouseMove olayları oluşturulur. MouseMove olay işleyicisi önce geçerli modun bir silme modu olup olmadığını ve herhangi bir fare düğmesine basılıp basılmadığını denetler; eğer bu durumlar mevcut değilse, olayı yoksayar. Ardından olay işleyicisi, oluşturucu nesnesinin PixelToInkSpace yöntemini kullanarak imlecin piksel koordinatlarını mürekkep alanı koordinatlarına dönüştürür ve geçerli silme moduna bağlı olarak kodun silme yöntemlerinden birini çağırır.
Vuruşları Silme
EraseStrokes
yöntemi, imlecin konumunu mürekkep alanında alır ve HitTestRadius
birim içinde bir vuruş koleksiyonu oluşturur.
currentStroke
parametresi silinmemesi gereken bir Stroke nesnesi belirtir. Ardından strokes koleksiyonu toplayıcıdan silinir ve form yeniden çizilir.
private void EraseStrokes(Point pt, Stroke currentStroke)
{
Strokes strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);
if (null!=currentStroke && strokesHit.Contains(currentStroke))
{
strokesHit.Remove(currentStroke);
}
myInkCollector.Ink.DeleteStrokes(strokesHit);
if (strokesHit.Count > 0)
{
this.Refresh();
}
}
Kesişimlerde Silme
EraseAtIntersections
yöntemi, test yarıçapı içindeki her vuruş üzerinde yinelenir ve bu vuruşla koleksiyondaki diğer tüm vuruşlar arasında bir kesişim dizisi oluşturur. Kesişimler bulunamazsa, tüm vuruş silinir; aksi takdirde, vuruşta test noktasına en yakın nokta bulunur ve bu noktadan itibaren, noktanın her iki tarafındaki kesişimler bulunur ve kaldırılacak segment tanımlanır.
Stroke nesnesinin Split yöntemi, segmenti vuruşun geri kalanından ayırmak için kullanılır ve ardından segment silinir ve vuruşun geri kalanı olduğu gibi bırakılır.
EraseStrokes
'de olduğu gibi, yöntem döndürmeden önce form yeniden çizilir.
private void EraseAtIntersections(Point pt)
{
Strokes strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);
foreach (Stroke currentStroke in strokesHit)
{
float[] intersections = currentStroke.FindIntersections(myInkCollector.Ink.Strokes);
...
float findex = currentStroke.NearestPoint(pt);
...
strokeToDelete = currentStroke.Split(intersections[i]);
...
}
...
}
Dönüm Noktalarında Silme
Test yarıçapı içindeki her vuruş için, EraseAtCusps
yöntemi, Stroke nesnesinin PolylineCusps metodundan cusp dizisini alır. Vuruşun her ucu da bir cusp'tır, bu nedenle vuruşta yalnızca iki sümük varsa, vuruşun tamamı silinir; aksi takdirde, vuruşta test noktasına en yakın nokta bulunur ve bundan sonra, noktanın her iki tarafındaki kesişimler bulunur ve kaldırılacak segment açıklanır.
Stroke nesnesinin Split yöntemi, segmenti vuruşun geri kalanından ayırmak için kullanılır ve ardından segment silinir ve vuruşun geri kalanı olduğu gibi bırakılır.
EraseStrokes
'de olduğu gibi, yöntem döndürmeden önce form yeniden çizilir.
private void EraseAtCusps(Point pt)
{
...
strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);
foreach (Stroke currentStroke in strokesHit)
{
int[] cusps = currentStroke.PolylineCusps;
...
float findex = currentStroke.NearestPoint(pt);
...
strokeToDelete = currentStroke.Split(cusps[i]);
myInkCollector.Ink.DeleteStroke(strokeToDelete);
...
}
...
}
Formu Kapatma
Formun Dispose yöntemi, InkCollector nesnesini myInkCollector
yok eder.