2014-08-28 40 views
0

我有這樣一個窗口:WPF鍵綁定不工作,因爲窗口不能集中eventhough可聚焦

<Window Background="LightBlue" Title="SHMD Ämneshantering" 
    x:Class="SHMD_Edit.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SHMD_Edit" 
    xmlns:localViewModels="clr-namespace:SHMD_Edit.ViewModels" 
    xmlns:localViews="clr-namespace:SHMD_Edit.Views" 
    Height="700" Width="1105" MinHeight="750" MinWidth="1005" Focusable="True" Name="window">...</Window> 

我想補充一點,在整個應用程序使用的按鍵組合,這樣的:

<Window.InputBindings> 
    <KeyBinding Gesture="CTRL+R" Command="{Binding AddSubstanceCommand}"/> 
</Window.InputBindings> 

但是,該命令將無法正常工作,除非我把焦點放在像我的一個列表視圖中的某個元素那樣可聚焦的東西上。我希望用戶能夠在任何地方運行該命令,因此我嘗試將焦點添加到窗口中,以確定稍後關注的任何內容都將成爲窗口的子項,因此手勢應該傳播到正確的目標。但是,我無法獲得關注窗口,因爲您看到我已將它設置爲可聚焦,並且在立即窗口中檢查時,我可以確認它確實是可聚焦的,但在其上運行Focus()會返回錯誤和焦點沒有設置。

如何將焦點設置到我的窗口?任何其他方式獲得全局可用的鍵綁定?

+0

我使空的窗口和'RelayCommand'工作。您需要在此處放置標記以重現問題。無論如何,爲什麼不能在Window中的任何位置放置任何元素(Visibility = Collapsed)並以編程方式在其上調用Focus()方法? – monstr 2014-08-28 13:18:10

+0

你在做什麼,我沒有設置datacontext到整個窗口,但它包含的網格,這就是爲什麼沒有它應該如此工作。 – 2014-09-03 10:50:10

回答

0

我已經實現了全局快捷方式,我認爲你缺少的是使用RoutedUICommands,它將處理通過可視化樹的命令路由。如果你不這樣做,你可能會陷入像你現在這樣奇怪的聚焦問題。另一個關鍵點是使用正確的CommandManager註冊方法,您想要使用CommandManager.RegisterClassCommandBindingCommandManager.RegisterClassInputBinding,並在任一情況下將您的類型設置爲Window,這顯然會使其可用於WPF全局。

下面是我用來爲我的應用程序創建快捷方式的兩個抽象類。

/// <summary> 
/// Defines the base class for application wide shortcuts. 
/// </summary> 
public abstract class ApplicationShortcut 
{ 
    /// <summary> 
    /// The <see cref="ICommand"/> to be executed. 
    /// </summary> 
    public abstract ICommand Command { get; } 

    /// <summary> 
    /// The <see cref="InputGesture"/> defining how the <see cref="ApplicationShortcut.Command"/> is invoked. 
    /// </summary> 
    public abstract InputGesture Shortcut { get; } 

    /// <summary> 
    /// Registers the <see cref="ApplicationShortcut"/> with the application. 
    /// </summary> 
    public abstract void RegisterShortcut(); 
} 

/// <summary> 
/// Base class that defines an <see cref="ICommand"/> that is routed through the element tree and contains a text property. 
/// </summary> 
/// <typeparam name="T">The type that is registered with the command.</typeparam> 
public abstract class RoutedUIShortcut<T> : ApplicationShortcut 
{ 
    /// <summary> 
    /// The type registered with the command. 
    /// </summary> 
    protected readonly Type OwnerType = typeof (T); 

    /// <summary> 
    /// The <see cref="RoutedUICommand"/> to be executed. 
    /// </summary> 
    protected abstract RoutedUICommand RoutedCommand { get; } 

    /// <summary> 
    /// The <see cref="ICommand"/> to be executed. 
    /// </summary> 
    public override sealed ICommand Command 
    { 
     get { return RoutedCommand; } 
    } 

    /// <summary> 
    /// Registers the <see cref="ApplicationShortcut"/> with the application. 
    /// </summary> 
    public override void RegisterShortcut() 
    { 
     CommandManager.RegisterClassCommandBinding(OwnerType, new CommandBinding(Command, OnExecuted, OnCanExecute)); 
    } 

    /// <summary> 
    /// Represents the method that will handle the <see cref="CommandBinding.CanExecute"/> routed event. 
    /// </summary> 
    /// <param name="sender">The command target that is invoking the handler.</param> 
    /// <param name="e">The event data.</param> 
    protected virtual void OnCanExecute(object sender, CanExecuteRoutedEventArgs e) 
    { 
     e.CanExecute = true; 
    } 

    /// <summary> 
    /// Represents the method that will handle the <see cref="CommandBinding.Executed"/> and <see cref="CommandBinding.PreviewExecuted"/> routed events, as well as related attached events. 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e">The event data.</param> 
    protected abstract void OnExecuted(object sender, ExecutedRoutedEventArgs e); 
} 

然後你只需要實例你的快捷課程時,你的應用程序啓動並調用RegisterShortcut()方法。