Görsel Katmanda Tıklama Testi

Bu konu, görsel katmanı tarafından sağlanan isabet testi işlevlerine genel bir bakış sağlar. İsabet testi desteği, bir geometri veya nokta değerinin Visualişlenen içeriği içinde olup olmadığını belirlemenize olanak tanır ve birden çok nesne seçmek için seçim dikdörtgeni gibi kullanıcı arabirimi davranışı uygulamanızı sağlar.

İsabetLi Test Senaryoları

sınıfı UIElement , belirli bir koordinat değeri kullanarak bir öğeye karşı teste isabet etmenizi sağlayan yöntemini sağlar InputHitTest . Çoğu durumda yöntemi, InputHitTest öğelerin isabet testini uygulamak için istenen işlevselliği sağlar. Ancak, görsel katmanında isabet testi uygulamanız gerekebilecek çeşitli senaryolar vardır.

  • Nesne olmayanUIElement nesnelere karşı isabet testi: Bu, veya grafik nesneleri gibi DrawingVisual nesne olmayanUIElement nesneleri test ediyorsanız geçerlidir.

  • Geometri kullanarak isabet testi: Bu, bir noktanın koordinat değeri yerine geometri nesnesi kullanarak teste isabet etmeniz gerekiyorsa geçerlidir.

  • Birden çok nesneye karşı isabet testi: Bu, çakışan nesneler gibi birden çok nesneye karşı teste basmanız gerektiğinde geçerlidir. Yalnızca ilki değil, geometri veya nokta kesişen tüm görseller için sonuçlar alabilirsiniz.

  • İsabet testi ilkesini yoksayma UIElement : Bu, bir öğenin devre dışı mı yoksa görünmez mi olduğu gibi faktörleri dikkate alan isabet testi ilkesini yoksaymanız UIElement gerektiğinde geçerlidir.

Dekont

Görsel katmanında isabet testini gösteren eksiksiz bir kod örneği için bkz . Çizim Kullanarak İsabet TestiVisuals Örneği ve Win32 Birlikte Çalışma Örneği ile İsabet Testi.

İsabet Testi Desteği

sınıfındaki VisualTreeHelper yöntemlerin HitTest amacı, geometri veya nokta koordinat değerinin denetim veya grafik öğesi gibi belirli bir nesnenin işlenmiş içeriği içinde olup olmadığını belirlemektir. Örneğin, bir nesnenin sınırlayıcı dikdörtgeninde fare tıklamasının dairenin geometrisi içinde olup olmadığını belirlemek için isabet testi kullanabilirsiniz. Ayrıca, kendi özel isabet testi hesaplamalarınızı gerçekleştirmek için varsayılan isabet testi uygulamasını geçersiz kılmayı da seçebilirsiniz.

Aşağıdaki çizimde dikdörtgen olmayan bir nesnenin bölgesi ile sınırlayıcı dikdörtgeni arasındaki ilişki gösterilmektedir.

Diagram of valid hit test region
Geçerli isabet testi bölgesinin diyagramı

İsabet Testi ve Z Sırası

Windows Presentation Foundation (WPF) görsel katmanı, yalnızca en üstteki nesneye değil, nokta veya geometri altındaki tüm nesnelere yönelik isabet testini destekler. Sonuçlar z sırasına göre döndürülür. Ancak, yöntemine parametre HitTest olarak geçirdiğiniz görsel nesne, görsel ağacının hangi bölümünün isabet testi olacağını belirler. Görsel ağacının tamamına veya herhangi bir bölümüne karşı teste basabilirsiniz.

Aşağıdaki çizimde, daire nesnesi hem kare hem de üçgen nesnelerin üstündedir. Yalnızca z sırası değeri en üstte olan görsel nesnesini isabet testiyle ilgileniyorsanız, ilk öğeden sonra isabet testi geçişinin durdurulması için görsel isabet testi sabit listesi'nden HitTestResultCallback döndürülecek Stop şekilde ayarlayabilirsiniz.

Diagram of the z-order of a visual tree
Görsel ağacın z sırasının diyagramı

Belirli bir nokta veya geometrinin altındaki tüm görsel nesneleri numaralandırmak istiyorsanız, içinden HitTestResultCallbackgeri dönünContinue. Bu, tamamen gizlenmiş olsalar bile diğer nesnelerin altındaki görsel nesneler için teste basabileceğiniz anlamına gelir. Daha fazla bilgi için "Hit Test Results Callback kullanma" bölümündeki örnek koda bakın.

Dekont

Saydam bir görsel nesne de isabet testi olabilir.

Varsayılan İsabet Testlerini Kullanma

Bir noktanın görsel nesnenin geometrisi içinde olup olmadığını belirlemek için yöntemini kullanarak HitTest bir görsel nesnesi ve test etmek için nokta koordinat değeri belirtebilirsiniz. Görsel nesne parametresi, isabet testi araması için görsel ağacındaki başlangıç noktasını tanımlar. Geometrisi koordinatı içeren görsel ağaçta bir görsel nesnesi bulunursa, nesnenin VisualHitHitTestResult özelliğine ayarlanır. HitTestResult daha sonra yönteminden HitTest döndürülür. Nokta, isabet sınaması yaptığınız görsel alt ağacıyla birlikte yoksa döndürür HitTestnull.

Dekont

Varsayılan isabet testi her zaman z düzeninde en üstteki nesneyi döndürür. Kısmen veya tamamen gizlenmiş olanlar bile olmak üzere tüm görsel nesneleri tanımlamak için bir isabet testi sonucu geri çağırması kullanın.

Yöntemin point parametresi HitTest olarak geçirdiğiniz koordinat değeri, test ettiğiniz görsel nesnenin koordinat alanına göre olmalıdır. Örneğin, üst öğesinin koordinat alanında (100, 100) tanımlı iç içe görsel nesneleriniz varsa, (0, 0) konumundaki bir alt görseli test etme isabeti, üst öğesinin koordinat alanında (100, 100) isabet testine eşdeğerdir.

Aşağıdaki kod, isabet testi için kullanılan olayları yakalamak için kullanılan bir UIElement nesne için fare olay işleyicilerinin nasıl ayarlandığını gösterir.

// Respond to the left mouse button down event by initiating the hit test.
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Retrieve the coordinate of the mouse position.
    Point pt = e.GetPosition((UIElement)sender);

    // Perform the hit test against a given portion of the visual object tree.
    HitTestResult result = VisualTreeHelper.HitTest(myCanvas, pt);

    if (result != null)
    {
        // Perform action on hit visual object.
    }
}
' Respond to the left mouse button down event by initiating the hit test.
Private Overloads Sub OnMouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    ' Retrieve the coordinate of the mouse position.
    Dim pt As Point = e.GetPosition(CType(sender, UIElement))

    ' Perform the hit test against a given portion of the visual object tree.
    Dim result As HitTestResult = VisualTreeHelper.HitTest(myCanvas, pt)

    If result IsNot Nothing Then
        ' Perform action on hit visual object.
    End If
End Sub

Görsel Ağaç İsabet Testini Nasıl Etkiler?

Görsel ağaçtaki başlangıç noktası, nesnelerin isabet testi numaralandırması sırasında hangi nesnelerin döndürüleceğini belirler. Sınamaya isabet etmek istediğiniz birden çok nesneniz varsa, görsel ağaçta başlangıç noktası olarak kullanılan görsel nesne, ilgilendiğiniz tüm nesnelerin ortak atası olmalıdır. Örneğin, aşağıdaki diyagramda hem düğme öğesini hem de çizim görselini isabet testiyle ilgileniyorsanız, görsel ağacındaki başlangıç noktasını her ikisinin ortak atası olarak ayarlamanız gerekir. Bu durumda, tuval öğesi hem düğme öğesinin hem de çizim görselinin ortak atasıdır.

Diagram of a visual tree hierarchy
Görsel ağaç hiyerarşisinin diyagramı

Dekont

özelliği, IsHitTestVisible türetilmiş bir nesnenin işlenmiş içeriğinin bir UIElementbölümünden isabet testi sonucu olarak döndürülüp döndürülemeyeceğini bildiren bir değer alır veya ayarlar. Bu, isabet testinde hangi görsel nesnelerin yer aldığını belirlemek için görsel ağacı seçmeli olarak değiştirmenize olanak tanır.

İsabet Testi Sonucu Geri Çağırma kullanma

Geometrisi belirtilen koordinat değerini içeren bir görsel ağaçtaki tüm görsel nesneleri numaralandırabilirsiniz. Bu, diğer görsel nesneler tarafından kısmen veya tamamen gizlenenler bile olmak üzere tüm görsel nesneleri tanımlamanızı sağlar. Bir görsel ağaçtaki görsel nesneleri listelemek için, isabet testi geri çağırma işleviyle yöntemini kullanın HitTest . Belirttiğiniz koordinat değeri bir görsel nesnede bulunduğunda isabet testi geri çağırma işlevi sistem tarafından çağrılır.

İsabet testi sonuçları numaralandırması sırasında görsel ağacı değiştiren herhangi bir işlem gerçekleştirmemelisiniz. Bir nesnenin geçiş yapılırken görsel ağaçtan eklenmesi veya kaldırılması öngörülemeyen davranışlara neden olabilir. Yöntem döndürdüğünde görsel ağacı HitTest güvenle değiştirebilirsiniz. İsabet testi sonuçları numaralandırması sırasında değerleri depolamak için gibi bir ArrayListveri yapısı sağlamak isteyebilirsiniz.

// Respond to the right mouse button down event by setting up a hit test results callback.
private void OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    // Retrieve the coordinate of the mouse position.
    Point pt = e.GetPosition((UIElement)sender);

    // Clear the contents of the list used for hit test results.
    hitResultsList.Clear();

    // Set up a callback to receive the hit test result enumeration.
    VisualTreeHelper.HitTest(myCanvas, null,
        new HitTestResultCallback(MyHitTestResult),
        new PointHitTestParameters(pt));

    // Perform actions on the hit test results list.
    if (hitResultsList.Count > 0)
    {
        Console.WriteLine("Number of Visuals Hit: " + hitResultsList.Count);
    }
}
' Respond to the right mouse button down event by setting up a hit test results callback.
Private Overloads Sub OnMouseRightButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    ' Retrieve the coordinate of the mouse position.
    Dim pt As Point = e.GetPosition(CType(sender, UIElement))

    ' Clear the contents of the list used for hit test results.
    hitResultsList.Clear()

    ' Set up a callback to receive the hit test result enumeration.
    VisualTreeHelper.HitTest(myCanvas, Nothing, New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt))

    ' Perform actions on the hit test results list.
    If hitResultsList.Count > 0 Then
        Console.WriteLine("Number of Visuals Hit: " & hitResultsList.Count)
    End If
End Sub

İsabet testi geri çağırma yöntemi, görsel ağacındaki belirli bir görsel nesnede isabet testi tanımlandığında gerçekleştirdiğiniz eylemleri tanımlar. Eylemleri gerçekleştirdikten sonra, diğer görsel nesnelerin numaralandırmasına devam edilip edilmeyeceğini belirleyen bir HitTestResultBehavior değer döndürürsiniz.

// Return the result of the hit test to the callback.
public HitTestResultBehavior MyHitTestResult(HitTestResult result)
{
    // Add the hit test result to the list that will be processed after the enumeration.
    hitResultsList.Add(result.VisualHit);

    // Set the behavior to return visuals at all z-order levels.
    return HitTestResultBehavior.Continue;
}
' Return the result of the hit test to the callback.
Public Function MyHitTestResult(ByVal result As HitTestResult) As HitTestResultBehavior
    ' Add the hit test result to the list that will be processed after the enumeration.
    hitResultsList.Add(result.VisualHit)

    ' Set the behavior to return visuals at all z-order levels.
    Return HitTestResultBehavior.Continue
End Function

Dekont

İsabet görseli nesnelerinin numaralandırma sırası z sırasına göredir. En üst z sırası düzeyindeki görsel nesne, numaralandırılmış ilk nesnedir. Numaralandırılan diğer tüm görsel nesneler z sırası düzeyinde azalan düzeydedir. Bu numaralandırma sırası, görsellerin işleme sırasına karşılık gelir.

döndürerek Stopisabet testi geri çağırma işlevinde görsel nesnelerin numaralandırmasını istediğiniz zaman durdurabilirsiniz.

// Set the behavior to stop enumerating visuals.
return HitTestResultBehavior.Stop;
' Set the behavior to stop enumerating visuals.
Return HitTestResultBehavior.Stop

İsabetLi Test Filtresi Geri Çağırma kullanma

İsabet testi sonuçlarına geçirilen nesneleri kısıtlamak için isteğe bağlı bir isabet testi filtresi kullanabilirsiniz. Bu, isabet testi sonuçlarınızda işlemekle ilgilenmediğiniz görsel ağacının bölümlerini yoksaymanıza olanak tanır. İsabet testi filtresi uygulamak için bir isabet testi filtresi geri çağırma işlevi tanımlar ve yöntemini çağırdığınızda HitTest bunu parametre değeri olarak geçirirsiniz.

// Respond to the mouse wheel event by setting up a hit test filter and results enumeration.
private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
    // Retrieve the coordinate of the mouse position.
    Point pt = e.GetPosition((UIElement)sender);

    // Clear the contents of the list used for hit test results.
    hitResultsList.Clear();

    // Set up a callback to receive the hit test result enumeration.
    VisualTreeHelper.HitTest(myCanvas,
                      new HitTestFilterCallback(MyHitTestFilter),
                      new HitTestResultCallback(MyHitTestResult),
                      new PointHitTestParameters(pt));

    // Perform actions on the hit test results list.
    if (hitResultsList.Count > 0)
    {
        ProcessHitTestResultsList();
    }
}
' Respond to the mouse wheel event by setting up a hit test filter and results enumeration.
Private Overloads Sub OnMouseWheel(ByVal sender As Object, ByVal e As MouseWheelEventArgs)
    ' Retrieve the coordinate of the mouse position.
    Dim pt As Point = e.GetPosition(CType(sender, UIElement))

    ' Clear the contents of the list used for hit test results.
    hitResultsList.Clear()

    ' Set up a callback to receive the hit test result enumeration.
    VisualTreeHelper.HitTest(myCanvas, New HitTestFilterCallback(AddressOf MyHitTestFilter), New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt))

    ' Perform actions on the hit test results list.
    If hitResultsList.Count > 0 Then
        ProcessHitTestResultsList()
    End If
End Sub

İsteğe bağlı isabet testi filtre geri çağırma işlevini sağlamak istemiyorsanız, yöntemi için HitTest parametresi olarak bir null değer geçirin.

// Set up a callback to receive the hit test result enumeration,
// but no hit test filter enumeration.
VisualTreeHelper.HitTest(myCanvas,
                  null,  // No hit test filtering.
                  new HitTestResultCallback(MyHitTestResult),
                  new PointHitTestParameters(pt));
' Set up a callback to receive the hit test result enumeration,
' but no hit test filter enumeration.
VisualTreeHelper.HitTest(myCanvas, Nothing, New HitTestResultCallback(AddressOf MyHitTestResult), New PointHitTestParameters(pt)) ' No hit test filtering.

Pruning a visual tree using a hit test filter
Görsel ağacı ayıklama

İsabet testi filtresi geri çağırma işlevi, işlenen içeriği belirttiğiniz koordinatları içeren tüm görselleri listelemenize olanak tanır. Ancak, isabet testi sonuçları geri çağırma işlevinizde işlemek istemediğiniz görsel ağacının belirli dallarını yoksaymak isteyebilirsiniz. isabet testi filtre geri çağırma işlevinin dönüş değeri, görsel nesnelerin numaralandırmasının ne tür bir eylem gerçekleştirmesi gerektiğini belirler. Örneğin, değerini döndürürseniz geçerli ContinueSkipSelfAndChildrengörsel nesnesini ve alt öğelerini isabet testi sonuçları numaralandırmasından kaldırabilirsiniz. Bu, isabet testi sonuçları geri çağırma işlevinin bu nesneleri numaralandırmasında göremeyeceği anlamına gelir. Nesnelerin görsel ağacının ayıklaması, isabet testi sonuçları numaralandırma geçişi sırasında işleme miktarını azaltır. Aşağıdaki kod örneğinde, filtre etiketleri ve alt öğeleri atlar ve diğer her şeyi test eder.

// Filter the hit test values for each object in the enumeration.
public HitTestFilterBehavior MyHitTestFilter(DependencyObject o)
{
    // Test for the object value you want to filter.
    if (o.GetType() == typeof(Label))
    {
        // Visual object and descendants are NOT part of hit test results enumeration.
        return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
    }
    else
    {
        // Visual object is part of hit test results enumeration.
        return HitTestFilterBehavior.Continue;
    }
}
' Filter the hit test values for each object in the enumeration.
Public Function MyHitTestFilter(ByVal o As DependencyObject) As HitTestFilterBehavior
    ' Test for the object value you want to filter.
    If o.GetType() Is GetType(Label) Then
        ' Visual object and descendants are NOT part of hit test results enumeration.
        Return HitTestFilterBehavior.ContinueSkipSelfAndChildren
    Else
        ' Visual object is part of hit test results enumeration.
        Return HitTestFilterBehavior.Continue
    End If
End Function

Dekont

İsabetli test sonuçları geri çağırmanın çağrılmadığı durumlarda isabet testi filtresi geri çağırması bazen çağrılır.

Varsayılan İsabet Testlerini Geçersiz Kılma

Yöntemini geçersiz HitTestCore kılarak görsel nesnesinin varsayılan isabet testi desteğini geçersiz kılabilirsiniz. Bu, yöntemini çağırdığınızda HitTest geçersiz kılınan uygulamanızın HitTestCore çağrıldığı anlamına gelir. Geçersiz kılınan yönteminiz, koordinat görsel nesnesinin işlenmiş içeriğinin dışında olsa bile isabet testi görsel nesnesinin sınırlayıcı dikdörtgeninin içinde olduğunda çağrılır.

// Override default hit test support in visual object.
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
    Point pt = hitTestParameters.HitPoint;

    // Perform custom actions during the hit test processing,
    // which may include verifying that the point actually
    // falls within the rendered content of the visual.

    // Return hit on bounding rectangle of visual object.
    return new PointHitTestResult(this, pt);
}
' Override default hit test support in visual object.
Protected Overrides Overloads Function HitTestCore(ByVal hitTestParameters As PointHitTestParameters) As HitTestResult
    Dim pt As Point = hitTestParameters.HitPoint

    ' Perform custom actions during the hit test processing,
    ' which may include verifying that the point actually
    ' falls within the rendered content of the visual.

    ' Return hit on bounding rectangle of visual object.
    Return New PointHitTestResult(Me, pt)
End Function

Bazen hem sınırlayıcı dikdörtgende hem de görsel nesnenin işlenmiş içeriğinde teste isabet etmek isteyebilirsiniz. geçersiz kılınan HitTestCore yönteminizdeki parametre değerini temel yöntemine HitTestCoreparametre olarak kullanarakPointHitTestParameters, bir görsel nesnesinin sınırlayıcı dikdörtgeninin isabetine dayalı eylemler gerçekleştirebilir ve ardından görsel nesnesinin işlenmiş içeriğine karşı ikinci bir isabet testi gerçekleştirebilirsiniz.

// Override default hit test support in visual object.
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
    // Perform actions based on hit test of bounding rectangle.
    // ...

    // Return results of base class hit testing,
    // which only returns hit on the geometry of visual objects.
    return base.HitTestCore(hitTestParameters);
}
' Override default hit test support in visual object.
Protected Overrides Overloads Function HitTestCore(ByVal hitTestParameters As PointHitTestParameters) As HitTestResult
    ' Perform actions based on hit test of bounding rectangle.
    ' ...

    ' Return results of base class hit testing,
    ' which only returns hit on the geometry of visual objects.
    Return MyBase.HitTestCore(hitTestParameters)
End Function

Ayrıca bkz.