안녕하세요. 김대욱입니다. 최근들어 터치스크린을 이용한 프로젝트를 자주 진행하다보니 이번 포스팅은 터치스크린을 이용하는 시스템에서 유용하게 사용될 수 있는 내용이 되겠습니다. 이번시간에 소개해 드릴 내용은 터치스크린을 사용하는 어플리케이션에서 TextBox등의 Control에 Focus 되었을때 자동으로 Screen Keyboard Application을 실행하는 예제입니다. 동영상을 보시면 쉽게 이해하실수 있습니다.
위 동영상에서는 WIndows에서 기본적으로 제공하는 OnScreenKeyboard를 사용했지만, 이번시간에 소개해 드릴 내용을 응용하면 직접 개발한 Keyboard Application을 사용하실 수도 있습니다. 간단하게 원리를 말씀드리자면 입력가능한 컨트롤 즉, TextBox나 PasswordBox에 Focus 되었을때 미리 지정해놓은 Keyboard Application을 실행하고 Focus를 잃었을때 Keyboard Application을 닫는 원리가 되겠습니다.
컨트롤 하나하나 일일이 Focus이벤트 코드를 추가하는 방법을 사용할수도 있겠지만, 이번시간에 소개해 드릴방법은 Attached DependencyProperty를 사용하여 간단하게 Screen Keyboard를 지원하도록 구현했습니다. 사용할때에는 아래와 같이 사용할 수 있습니다.
-
- <StackPanel osk:OSKHelper.IsSurpportScreenKeyboard="True">
- <TextBox/>
- <TextBox/>
- <PasswordBox />
- </StackPanel>
-
-
- <StackPanel osk:OSKHelper.IsSurpportScreenKeyboard="True">
- <TextBox/>
- <TextBox osk:OSKHelper.IsSurpportScreenKeyboard="False"/>
- <PasswordBox />
- </StackPanel>
-
-
- <StackPanel >
- <TextBox osk:OSKHelper.IsSurpportScreenKeyboard="True"/>
- <TextBox osk:OSKHelper.IsSurpportScreenKeyboard="False"/>
- <PasswordBox osk:OSKHelper.IsSurpportScreenKeyboard="True"/>
- </StackPanel>
아래는 Attached DependencyProperty를 구현한 소스코드입니다.
- public static class OSKHelper
- {
-
-
- public static string ScreenKeyboardFile = "osk.exe";
- public static Process ScreenKeyboardInstance = null;
-
-
- private static RoutedEventHandler FocusEventHandler = new RoutedEventHandler(FocusHandler);
-
-
- public static readonly DependencyProperty IsSurpportScreenKeyboardProperty =
- DependencyProperty.RegisterAttached("IsSurpportScreenKeyboard", typeof(bool?),
- typeof(OSKHelper),
- new FrameworkPropertyMetadata(null, new PropertyChangedCallback(IsSurpportScreenKeyboardChanged)));
-
- public static bool GetIsSurpportScreenKeyboard(FrameworkElement Target)
- {
- return (bool)Target.GetValue(IsSurpportScreenKeyboardProperty);
- }
-
- public static void SetIsSurpportScreenKeyboard(FrameworkElement Target, bool? Value)
- {
- Target.SetValue(IsSurpportScreenKeyboardProperty, Value);
- }
-
-
- public static void IsSurpportScreenKeyboardChanged(DependencyObject Sender, DependencyPropertyChangedEventArgs e)
- {
- FrameworkElement Target = Sender as FrameworkElement;
-
-
- if ((bool)e.NewValue )
- {
- Target.GotFocus += FocusEventHandler;
- Target.LostFocus += FocusEventHandler;
- }
-
-
- else if (FocusEventHandler.GetInvocationList().First().Target == Target)
- {
- Target.GotFocus -= FocusEventHandler;
- Target.LostFocus -= FocusEventHandler;
- }
- }
-
-
- static void FocusHandler(object sender, RoutedEventArgs e)
- {
- FrameworkElement Target = sender as FrameworkElement;
- FrameworkElement Source = e.Source as FrameworkElement;
-
-
- if ((bool?)Target.GetValue(IsSurpportScreenKeyboardProperty) == false)
- {
- Target.GotFocus -= FocusEventHandler;
- Target.GotFocus -= FocusEventHandler;
- return;
- }
-
-
- else if ((bool?)Source.GetValue(IsSurpportScreenKeyboardProperty) != false &&
- e.RoutedEvent == FocusManager.GotFocusEvent && (e.Source is TextBox || e.Source is PasswordBox))
- {
- ScreenKeyboardInstance = Process.Start(ScreenKeyboardFile);
- }
-
- else if (e.RoutedEvent == FocusManager.LostFocusEvent && ScreenKeyboardInstance != null)
- {
- if (ScreenKeyboardInstance.HasExited == false)
- ScreenKeyboardInstance.CloseMainWindow();
- ScreenKeyboardInstance = null;
- }
-
- }
-
- }
동작원리는 위에서 설명드린것과 동일하며 Attached Dependency Property를 이해하고 있다면, 어렵지 않게 이해하실수 있을것 같습니다 ^^