IT

WPF : TextBox에서 프로그래밍 방식으로 포커스를 제거하는 방법

lottoking 2020. 9. 15. 08:02
반응형

WPF : TextBox에서 프로그래밍 방식으로 포커스를 제거하는 방법


내 WPF에 간단한 (적어도 그랬다고 생각한) 동작을 추가하고 싶습니다 TextBox.

사용자가 탈출 키를 TextBox편집을 시작했을 때 사용자가 편집을 시작했을 때의 텍스트를 가지게하고 TextBox.

편집 시작 부분에 코드 값에 대한 텍스트를 설정하는 데 문제가 없습니다.

문제는 요소의 증가를 제거하는 것입니다. 포커스를 다른 구성 요소로하고 싶지 TextBox않고 포커스를 잃고 싶을뿐입니다 . 늘어나는 것을 TextBox잃을 수 없는 요소가 늘어나는 것입니까?


.NET Framework 4에서 Keyboard.ClearFocus();


내가 사용하고있는 코드 :

// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)textBox.Parent;
while (parent != null && parent is IInputElement && !((IInputElement)parent).Focusable)
{
    parent = (FrameworkElement)parent.Parent;
}

DependencyObject scope = FocusManager.GetFocusScope(textBox);
FocusManager.SetFocusedElement(scope, parent as IInputElement);

파티에 조금 늦었습니다.

닷넷 3.0 이후 로 나를 위해 트릭을 수행 FrameworkElementMoveFocus 기능이 있습니다.


포커스 가능한 상위 항목에 포커스를 수 있습니다. 이 코드는 텍스트 상자가 동일한 템플릿 기본 포커스 가능한 조상이없는 템플릿 내부에있는 경우에도 작동합니다.

DependencyObject ancestor = textbox.Parent;
while (ancestor != null)
{
    var element = ancestor as UIElement;
    if (element != null && element.Focusable)
    {
        element.Focus();
        break;
    }

    ancestor = VisualTreeHelper.GetParent(ancestor);
}

AFAIK, 넓어짐을 완전히 제거하는 것은 불가능합니다. 창에있는 항목은 항상 포커스를 갖습니다.


위의 답변 중 어느 것도 저에게 효과가 없었고 수락 된 답변은 키보드 포커스 작동 방식에 접근 방식에 도달했습니다.

// Kill logical focus
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
// Kill keyboard focus
Keyboard.ClearFocus();

어디에서나 키보드 포커스를 모두 죽입니다.


Windows Phone 개발에서 방금 수행 Focus()했거나 PhoneApplicationPagethis.Focus() 에서 수행 기능 매력처럼 작동했습니다.


저에게는 특히 LostFocus 바인딩과 함께 사용할 때 매우 까다 롭습니다. 그러나 내 해결 방법은 빈 레이블을 추가하고 업데이트를 맞추는 것입니다.

<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />

...

OnKeyDown(object sender, RoutedEventArgs e)
{
  //if is Esc
  ResetFocusArea.Focus();
}

내 대답은 위의 질문을 직접적으로 다루지는 않지만 그 표현이 프로그래밍 방식으로 늘어나는 것을 제거하는 것입니다. 이것이 필요한 시나리오는 사용자가 창과 같은 루트 컨트롤의 배경을 마우스 왼쪽 버튼으로 클릭 할 때 포커스를 지울 수있는 것입니다.

따라서이를 달성하기 위해 동적으로 생성 된 컨트롤 (제 경우에는 빈 레이블)로 포커스를 전환하는 첨부 된 동작을 만들 수 있습니다. 더미 레이블을 추가 할 수있는 패널을 찾기 위해 하위 항목을 반복 수행하는 창과 같은 최상위 요소에서 동작을 사용하는 것이 좋습니다.

public class LoseFocusOnLeftClick : Behavior<FrameworkElement>
{
    private readonly MouseBinding _leftClick;
    private readonly Label _emptyControl = new Label() { Focusable = true, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top };

    public LoseFocusOnLeftClick()
    {
        _leftClick = new MouseBinding(new RelayCommand(LoseFocus), new MouseGesture(MouseAction.LeftClick));
    }

    protected override void OnAttached()
    {
        AssociatedObject.InputBindings.Add(_leftClick);
        AssociatedObject.Loaded += AssociatedObject_Loaded;
    }        

    protected override void OnDetaching()
    {
        AssociatedObject.InputBindings.Remove(_leftClick);
        AssociatedObject.Loaded -= AssociatedObject_Loaded;
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Loaded -= AssociatedObject_Loaded;

        AttachEmptyControl();
    }

    private void AttachEmptyControl()
    {            
        DependencyObject currentElement = AssociatedObject;
        while (!(currentElement is Panel))
        {
            currentElement = VisualTreeHelper.GetChild(currentElement, 0);
        }

        ((Panel)currentElement).Children.Add(_emptyControl);
    }

    private void LoseFocus()
    {            
        _emptyControl.Focus();
    }
}

참고 URL : https://stackoverflow.com/questions/2914495/wpf-how-to-programmatically-remove-focus-from-a-textbox

반응형