[WPF] 키보드 포커스 가져오기 / 삭제하기


키보드로 컨트롤이 절실한 경우가 있다. 컨트롤 들의 미세한 컨트를을 위해서 이다.(예를 들면 Slider 류) 

그런데 한 화면에 Textbox 가 있고, 이것은 키보드 포커스를 뺏어가서 반환 하지 않는다. 그래서 아래와 같은 방법으로 처리 할 수 있다.



0. 그전에, 사용자의 컨트롤 밖에 클릭을 감지 하기 위해 현제 윈도우의 마우스 이벤트를 이용하여 포커스를 죽여도 좋다는 상황을 만들어 보자.

아래의 메서드를 이용한다.


        /*
         * 사용방법
         *  Window.GetWindow(this).PreviewMouseDown += MainWindow_PreviewMouseDown;
         *          ...
         *  void MainWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                Window.GetWindow(this).PreviewMouseDown -= MainWindow_PreviewMouseDown;
                Point pt = e.GetPosition((UIElement)sender);
                bool result = HitUtil.HitVisualFromMainWindow(pt, this);
         
                Console.WriteLine(">>>>>>>>>>>>" + result);
                if (result == false)
                {
                    //out interesting
                }
            }
         * 
         * 
         * */

        public static bool HitVisualFromMainWindow(Point globalMousePoint, UIElement target)
        {
            Window window = Window.GetWindow(target);

            Point actualTargetPoint = target.TransformToAncestor(window).Transform(new Point(0, 0));
            Point r_pt = new Point(globalMousePoint.X - actualTargetPoint.X, globalMousePoint.Y - actualTargetPoint.Y);
            HitTestResult result = VisualTreeHelper.HitTest(target, r_pt);
            if (result != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


그럼 위의 메서드를 활용하여 ..




1. 텍스트 박스의 포커스를 반환 하는법

        //-----------------------------------------------------------------events

        private void _tf_GotKeyboardFocus_1(object sender, KeyboardFocusChangedEventArgs e)
        {
            Window.GetWindow(this).PreviewMouseDown -= MainWindow_PreviewMouseDown;
            Window.GetWindow(this).PreviewMouseDown += MainWindow_PreviewMouseDown;
        }

        private void MainWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Window.GetWindow(this).PreviewMouseDown -= MainWindow_PreviewMouseDown;
            Point pt = e.GetPosition((UIElement)sender);
            bool result = HitUtil.HitVisualFromMainWindow(pt, this);
            if (result == false)
            {
                Keyboard.ClearFocus();
            }
        }


바로 Keyboard.ClearFocus() 를 호출하면 깔끔히 포커스를 반환 한다





2. 그렇다면, 이제 다른 컨트롤에 포커스를 할당 하여 보자. (마우스로 클릭과 동시에...)


        public SNCircleThumb()
        {
            InitializeComponent();
            this.Focusable = true; //중요!
        }





        //----------------------------------------------------------events

        #region

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            this.Focus(); //중요!

            Console.WriteLine("req focus");
        }

        //키보드 테스트
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            base.OnPreviewKeyDown(e);
            Console.WriteLine("press Key : " + e.Key);
        }


 중요 라고 주석 한 곳을 참고 한다.

ㅁㅁ




위 와 같은 방법으로 비 텍스트필드 류의 컨트롤 에도 포커스를 할당 할 수 있다.


Yamecoder 야매코더_
C# 2015. 1. 6. 18:15

댓글을 달아 주세요

Powerd by Tistory, designed by criuce
rss