2011-01-27 44 views
10

Tôi lấy được một điều khiển từ FrameworkElement để sử dụng như một vùng chứa cho VisualCollection, vì tôi đang thực hiện rất nhiều hiển thị tùy chỉnh bằng cách sử dụng DrawingVisuals (tạo bản đồ trò chơi).WPF UIElement.IsHitTestVisible = false; vẫn quay trở lại?

Tôi có một vài trường hợp khác nhau của vùng chứa được xếp chồng lên nhau và tôi chỉ muốn thử nghiệm ảnh hưởng đến lớp hiện có, vì vậy tôi đã thử làm rõ ràng và đặt .IsHitTestVisible = false, theo MSDN nên ngăn chặn bất kỳ phần tử con nào được trả lại dưới dạng kết quả trúng.

Tuy nhiên, tôi vẫn nhận được lần truy cập được trả lại trên vùng chứa được đặt .IsHitTestVisible = false. Tôi đã thử mọi thứ khác mà tôi có thể nghĩ đến, Đã thu gọn, Ẩn, Bị vô hiệu hóa, 0 Độ mờ, không có gì dường như đưa nó ra khỏi thử nghiệm lần truy cập.

+0

Cách giải quyết duy nhất mà tôi đã tìm thấy cho đến nay là để thực sự loại bỏ sự kiểm soát container từ đó là bộ sưu tập cha mẹ , để nó hoàn toàn nằm ngoài hệ thống phân cấp VisualTree. –

Trả lời

13

Tôi nghĩ đó là lỗi. Tôi đã sử dụng Reflector để hiểu tại sao phương thức HitTest trả về các mục vô hình và tôi thấy rằng không có kiểm tra khả năng hiển thị.

Giải pháp của tôi là sử dụng quá tải hitTest với bộ lọc:

public static HitTestFilterBehavior HitTestFilterInvisible(DependencyObject potentialHitTestTarget) 
{ 
    bool isVisible = false; 
    bool isHitTestVisible = false; 

    var uiElement = potentialHitTestTarget as UIElement; 
    if (uiElement != null) 
    { 
     isVisible = uiElement.IsVisible; 
     if (isVisible) 
     { 
      isHitTestVisible = uiElement.IsHitTestVisible; 
     } 
    } 
    else 
    { 
     UIElement3D uiElement3D = potentialHitTestTarget as UIElement3D; 
     if (uiElement3D != null) 
     { 
      isVisible = uiElement3D.IsVisible; 
      if (isVisible) 
      { 
       isHitTestVisible = uiElement3D.IsHitTestVisible; 
      } 
     } 
    } 

    if (isVisible) 
    { 
     return isHitTestVisible ? HitTestFilterBehavior.Continue : HitTestFilterBehavior.ContinueSkipSelf; 
    } 

    return HitTestFilterBehavior.ContinueSkipSelfAndChildren; 
} 
... 
// usage: 

    VisualTreeHelper.HitTest(
     myHitTestReference, 
     HitTestFilterInvisible, 
     hitTestResult => 
     { 
      // code to handle element which is visible to the user and enabled for hit testing. 
     }, 
     new PointHitTestParameters(myHitTestPoint)); 

Tôi hy vọng nó sẽ giúp bạn

+1

Mặc dù tôi đã hy vọng cho một cách để làm cho hành vi làm việc như MSDN mô tả chứ không phải là một workaround, điều này là hữu ích vì vậy tôi sẽ đánh dấu nó như là câu trả lời. –

+2

Tôi gặp vấn đề tương tự với đường viền là một phần của mẫu scrollviewer ... Tôi có một đường viền ở phía dưới tạo một bóng "gợi ý" để người dùng biết nội dung có thể cuộn được, nhưng đường viền đang chặn chuột sự kiện từ nội dung bên dưới nó ... Tôi đã thiết lập IsHitTestVisible = "false" trên biên giới nhưng nó vẫn nhận được sự kiện chuột. Thật không may tôi không phải đối phó với bất kỳ mã đằng sau các tập tin vì vậy tôi không thể ghi đè lên các phương pháp kiểm tra hit ... bất kỳ ý tưởng? – Valerie

Các vấn đề liên quan