2016-09-12 1 views
0

컨트롤을 선택할 때 컨트롤에 추가되는 사용자 정의 adorner가 있습니다. 문제는 또한 포커스가있을 때 텍스트 상자의 모든 텍스트를 자동으로 선택하도록 등록 된 사용자 지정 전역 이벤트가 있습니다.TextBox 텍스트를 선택하면 Adorner가 끌리지 않음

내가 아는 문제는 선택한 텍스트가있는 텍스트 상자에서 사용하려고 할 때 내 adorner가 작동하지 않는다는 것입니다. 어떤 이유로 그것은 선택된 텍스트를 대신 드래그하려고합니다. 이상한 점은 선택한 텍스트를 드래그 할 수 있다는 것입니다. 그런 다음 드롭이 완료되면 내 adorner를 사용할 수 있습니다. 왜 또는 어떻게 수정해야할지 모르겠습니다.

개별 텍스트 상자에서 끌기 명령을 취소하려고 시도했지만 adorner가 작동하지 않습니다.

내가 선택한 텍스트보다 adorner에게 더 높은 우선 순위를 부여 할 수있는 방법이 있습니까? 여기

여기
public class DraggingAdorner : Adorner 
{ 

    Thumb draggingIcon = null; 
    Thumb resizeThumb = null; 
    Border border = null; 

    VisualCollection visualChildren; 

    public DraggingAdorner(UIElement adornedElement) 
     : base(adornedElement) 
    { 
     visualChildren = new VisualCollection(this); 

     BuildBorder(); 
     BuildDraggingIcon(); 
     BuildResizer(); 

     draggingIcon.DragDelta += DraggingIcon_DragDelta; 
     resizeThumb.DragDelta += Resize; 
     resizeThumb.MouseDoubleClick += ResizeThumb_MouseDoubleClick; 
    } 

    private void ResizeThumb_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
    { 
     FrameworkElement adornedElement = this.AdornedElement as FrameworkElement; 
     Thumb hitThumb = sender as Thumb; 

     if (adornedElement == null || hitThumb == null) return; 
     FrameworkElement parentElement = adornedElement.Parent as FrameworkElement; 

     var tb = adornedElement as TextBox; 
     if (tb == null) return; 

     tb.Height = Double.NaN; 
     tb.Width = Double.NaN; 

     e.Handled = true; 
    } 

    private void BuildBorder() 
    { 
     if (border != null) return; 

     border = new Border(); 
     border.BorderBrush = new SolidColorBrush(Colors.Black); 
     border.BorderThickness = new Thickness(1); 
     border.Opacity = .5; 

     visualChildren.Add(border); 
    } 

    private void BuildDraggingIcon() 
    { 
     if (draggingIcon != null) return; 

     draggingIcon = new Thumb(); 

     draggingIcon.Cursor = Cursors.Hand; 
     draggingIcon.Height = draggingIcon.Width = 12; 
     draggingIcon.Opacity = 0.40; 
     draggingIcon.Background = new SolidColorBrush(Colors.Black); 

     visualChildren.Add(draggingIcon); 
    } 

    private void BuildResizer() 
    { 
     if (resizeThumb != null) return; 

     resizeThumb = new Thumb(); 

     // Set some arbitrary visual characteristics. 
     resizeThumb.Cursor = Cursors.ScrollAll; 
     resizeThumb.Height = resizeThumb.Width = 10; 
     resizeThumb.Opacity = 0.40; 
     resizeThumb.Background = new SolidColorBrush(Colors.Red); 

     visualChildren.Add(resizeThumb); 
    } 

    private void DraggingIcon_DragDelta(object sender, DragDeltaEventArgs e) 
    { 
     FrameworkElement adornedElement = this.AdornedElement as FrameworkElement; 
     Thumb hitThumb = sender as Thumb; 

     if (adornedElement == null || hitThumb == null) return; 
     FrameworkElement parentElement = adornedElement.Parent as FrameworkElement; 

     var left = e.HorizontalChange + Canvas.GetLeft(adornedElement); 
     if (left <= 0) 
     { 
      left = 1; 
     } 
     else if (left + adornedElement.ActualWidth >= parentElement.ActualWidth) 
     { 
      left = parentElement.ActualWidth - adornedElement.ActualWidth - 1; 
     } 

     var top = e.VerticalChange + Canvas.GetTop(adornedElement); 
     if (top <= 0) 
     { 
      top = 1; 
     } 
     else if (top + adornedElement.ActualHeight >= parentElement.ActualHeight) 
     { 
      top = parentElement.ActualHeight - adornedElement.ActualHeight - 1; 
     } 

     Canvas.SetLeft(adornedElement, left); 
     Canvas.SetTop(adornedElement, top); 
    } 

    // Handler for resizing from the bottom-right. 
    private void Resize(object sender, DragDeltaEventArgs e) 
    { 
     FrameworkElement adornedElement = this.AdornedElement as FrameworkElement; 
     Thumb hitThumb = sender as Thumb; 

     if (adornedElement == null || hitThumb == null) return; 
     FrameworkElement parentElement = adornedElement.Parent as FrameworkElement; 

     // Ensure that the Width and Height are properly initialized after the resize. 
     EnforceSize(adornedElement); 

     var left = Canvas.GetLeft(adornedElement); 
     var top = Canvas.GetTop(adornedElement); 

     var newWidth = Math.Max(adornedElement.Width + e.HorizontalChange, hitThumb.DesiredSize.Width); 
     var newHeight = Math.Max(e.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height); 

     if (left + newWidth >= parentElement.ActualWidth) 
     { 
      newWidth = parentElement.ActualWidth - left; 
     } 
     if (top + newHeight >= parentElement.ActualHeight) 
     { 
      newHeight = parentElement.ActualHeight - top; 
     } 

     adornedElement.Width = newWidth; 
     adornedElement.Height = newHeight; 
    } 

    private void EnforceSize(FrameworkElement adornedElement) 
    { 
     if (adornedElement.Width.Equals(Double.NaN)) 
      adornedElement.Width = adornedElement.DesiredSize.Width; 
     if (adornedElement.Height.Equals(Double.NaN)) 
      adornedElement.Height = adornedElement.DesiredSize.Height; 

     FrameworkElement parent = adornedElement.Parent as FrameworkElement; 
     if (parent != null) 
     { 
      adornedElement.MaxHeight = parent.ActualHeight; 
      adornedElement.MaxWidth = parent.ActualWidth; 
     } 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     double desiredWidth = AdornedElement.DesiredSize.Width; 
     double desiredHeight = AdornedElement.DesiredSize.Height; 

     double adornerWidth = this.DesiredSize.Width; 
     double adornerHeight = this.DesiredSize.Height; 

     draggingIcon.Arrange(new Rect(-adornerWidth/2, -adornerHeight/2, adornerWidth, adornerHeight)); 
     resizeThumb.Arrange(new Rect(desiredWidth - adornerWidth/2, desiredHeight - adornerHeight/2, adornerWidth, adornerHeight)); 
     border.Arrange(new Rect(0, 0, adornerWidth, adornerHeight)); 

     return finalSize; 
    } 

    protected override int VisualChildrenCount { get { return visualChildren.Count; } } 
    protected override Visual GetVisualChild(int index) { return visualChildren[index]; } 
} 

내 글로벌 이벤트 핸들러

protected override void OnStartup(StartupEventArgs e) 
{ 
    EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, new RoutedEventHandler(OnTextBoxFocus)); 
    EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(OnTextBoxFocus)); 

    base.OnStartup(e); 
} 

private void OnTextBoxFocus(object sender, RoutedEventArgs e) 
{ 
    var tb = sender as System.Windows.Controls.TextBox; 
    if (tb == null) return; 

    if (!String.IsNullOrWhiteSpace(tb.Text)) 
     tb.SelectAll(); 
} 

마지막으로는, 여기에 코드입니다 adorner 여기

private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{ 
    e.Handled = AdornSelectedElement(sender as UIElement); 
} 

private bool AdornSelectedElement(UIElement element) 
{ 
    if (element == null) return false; 

    RemoveSelectedElement(); 
    if (Canvas.GetLeft(element) < 0) 
     Canvas.SetLeft(element, 1); 

    var aLayer = AdornerLayer.GetAdornerLayer(element); 
    if ((aLayer.GetAdorners(element)?.Length ?? 0) > 0) return false; 
    aLayer.Add(new DraggingAdorner(element)); 
    selectedElement = element; 
    return true; 
} 

private void RemoveSelectedElement() 
{ 
    if (selectedElement == null) return; 

    var aLayer = AdornerLayer.GetAdornerLayer(selectedElement); 

    if ((aLayer.GetAdorners(selectedElement)?.Length ?? 0) < 1) return; 

    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]); 
    selectedElement = null; 
} 

을 적용하려면 코드 내 사용자 정의 adorner입니다 선택한 텍스트의 내부 끌기를 취소하려면 작동하지 않는

DataObject.AddCopyingHandler(tb, (s, e) => 
{ 
    if (e.IsDragDrop) 
    { 
     e.CancelCommand(); 
    } 
}); 

필자는 필요한 코드를 더 추가 할 예정입니다.

편집 : TextBox의 선택한 텍스트 때문이라고 생각하지 않습니다. 내 adorner와 textbox에 이상한 점이 있다고 생각하지만 무엇이 확실하지 않습니다. 잘 작동하는 사용자 지정 이미지 컨트롤이 있습니다.

SECOND EDIT : 실제로 텍스트 상자를 선택한 후에 IE에서 주 창을 닫고 다른 컨트롤을 클릭하는 등의 작업을 수행 할 수없는 것 같습니다. 어떤 이유에서 선택이 부적절하게 처리되어야하고 이상한 드래그 텍스트 모드를 종료하지 않는 이상한 일이 발생합니다. 텍스트를 드래그 앤 드롭해야합니다. 그런 다음에 내가 원하는 모든 것을 다시 할 수 있습니다.

답변

0

제가 일종의 문제를 파악했습니다. 이 방법을 끄십시오

private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{ 
    e.Handled = AdornSelectedElement(sender as UIElement); 
} 

텍스트 상자에 문제가 발생 했습니까? e.Handled를 true로 설정하여이 선택이 제대로 실행되도록 설정하는 사용자 정의 이미지 컨트롤이 있지만 TextBoxes에서 이것은 선택된 텍스트 드래그 문제를 발생시킵니다. 나는

return element is ImageBox; 

를 읽어 내

AdornSelectedElement  

루틴의 끝에서

return true; 

을 변경하고 그것을 고정. 누구나 이것이 왜 사용자 정의 컨트롤의 Xaml을 제공 할 수 있는지 알고 있다면 왜 이런 일이 일어 났는지 논의 할 수 있습니다.

감사합니다.

관련 문제