컨트롤을 선택할 때 컨트롤에 추가되는 사용자 정의 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에서 주 창을 닫고 다른 컨트롤을 클릭하는 등의 작업을 수행 할 수없는 것 같습니다. 어떤 이유에서 선택이 부적절하게 처리되어야하고 이상한 드래그 텍스트 모드를 종료하지 않는 이상한 일이 발생합니다. 텍스트를 드래그 앤 드롭해야합니다. 그런 다음에 내가 원하는 모든 것을 다시 할 수 있습니다.