Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
RegisterKeyBindingBehavior.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.Windows;
8 using System.Windows.Input;
9 
10 using SiliconStudio.Core;
11 using SiliconStudio.Presentation.Core;
12 using SiliconStudio.Presentation.Extensions;
13 using System.Windows.Data;
14 using System.Windows.Interactivity;
15 using System.Threading;
16 
17 namespace SiliconStudio.Presentation.Behaviors
18 {
19  public class RegisterKeyBindingBehavior : Behavior<FrameworkElement>
20  {
21  public KeyGesture KeyGesture
22  {
23  get { return (KeyGesture)GetValue(KeyGestureProperty); }
24  set { SetValue(KeyGestureProperty, value); }
25  }
26 
27  public static readonly DependencyProperty KeyGestureProperty = DependencyProperty.Register(
28  "KeyGesture",
29  typeof(KeyGesture),
31 
32  private IDisposable bindingRegistration;
33 
34  protected override void OnAttached()
35  {
36  if ((AssociatedObject is ICommandSource) == false)
37  {
38  var message = string.Format("The Host of a '{0}' must be of type '{1}'",
39  typeof(RegisterKeyBindingBehavior).Name,
40  typeof(ICommandSource).FullName);
41  throw new InvalidOperationException(message);
42  }
43 
44  SpawnCommandBindingResolutionCheckThread();
45  }
46 
47  private void SpawnCommandBindingResolutionCheckThread()
48  {
49  // Warning: a very bad method to do it (maybe the worst) but I didn't find a better one yet!
50 
51  ThreadPool.QueueUserWorkItem(
52  state =>
53  {
54  var host = (DependencyObject)state;
55  var commandSource = (ICommandSource)state;
56 
57  Func<bool> checkFunc = () =>
58  {
59  if (commandSource.Command != null)
60  {
61  OnCommandBindingResolved();
62  return true;
63  }
64  return false;
65  };
66 
67  while (true)
68  {
69  if ((bool)host.Dispatcher.Invoke(checkFunc))
70  break;
71  Thread.Sleep(10);
72  }
73  },
74  AssociatedObject);
75  }
76 
77  private void OnCommandBindingResolved()
78  {
79  var rootWindow = Window.GetWindow(AssociatedObject);
80  if (rootWindow == null)
81  return;
82 
83  var localCommand = ((ICommandSource)AssociatedObject).Command;
84  var localKeyGesture = KeyGesture;
85 
86  if (localCommand == null || localKeyGesture == null)
87  return;
88 
89  var binding = new KeyBinding(localCommand, localKeyGesture);
90 
91  bindingRegistration = new AnonymousDisposable(() => rootWindow.InputBindings.Remove(binding));
92  rootWindow.InputBindings.Add(binding);
93  }
94 
95  protected override void OnDetaching()
96  {
97  if (bindingRegistration != null)
98  {
99  bindingRegistration.Dispose();
100  bindingRegistration = null;
101  }
102  }
103  }
104 }
This class allows implementation of IDisposable using anonymous functions. The anonymous function wil...