[英]Child view focus in MVVM application to see Command
我正在開發MVVM應用程序。 我有一個主窗口,看起來或多或少像這樣:
<Window>
<ContentControl Content={Binding ContentViewModel} />
</Window>
然后,我有了這個ViewModel,它公開了一定數量的Command,並且我希望這些命令既可以從UI(帶有按鈕等)也可以從用戶使用KeyBindings從鍵盤(對用戶)可用。
這些命令可以從UI按鈕正常工作。 但是鍵綁定並不總是有效,在我看來,問題在於加載的視圖並非始終處於焦點位置。 這是該視圖的代碼。
<UserControl>
<UserControl.InputBindings>
<KeyBinding Key="Delete" Command="{Binding RemoveEntityCommand, ElementName=Designer}" />
</UserControl.InputBindings>
<Grid>
<namespace:Designer x:Name="Designer" />
</Grid>
</UserControl>
如何為MVVM應用永久解決此問題? 我已經多次遇到此問題。
注意:為簡單起見,刪除了所有名稱空間聲明。
謝謝。
我可能會將Command附加到Window
的KeyDown或KeyUp事件而不是UserControl
,然后從那里路由它。
可以將其路由到ShellViewModel
,然后在需要時將其傳遞給當前的ContentViewModel
,或者使用某種廣播特殊鍵組合的消息系統,而ViewModel可以訂閱它們。
我要做的是實現一個PreviewKeyUp事件,並使用該事件在我的視圖模型上調用方法,如下所示:
protected void PreviewKeyUp(object sender, KeyEventArgs args)
{
args.Handled = myViewModel.HandleKeyUp(args.Key);
}
public bool HandleKeyUp(Key key)
{
// Determine if you should execute a command
if(myCommands.ShouldExecuteOnKey(key))
{
// Execute the commad
return true;
}
return false;
}
許多人似乎認為MVVM 並不意味着沒有任何代碼后置 ,但這並不總是正確的,甚至不可能。
是的,鍵綁定很痛苦。 我同意Rachel的觀點,在這種特定情況下,您可能希望在窗口級別提供一些可用的功能。
您可以通過執行以下操作來避免出現代碼隱藏並獲得mvvm的好處:
很明顯,這是基礎架構的一部分工作,一旦安裝就可以測試和重用。 在這種情況下,由於您希望綁定在窗口級別可用,因此ShellVm保留命令並根據需要委托給子視圖模型。 我在下面只剩下了足夠的代碼,可以使您對該想法有所了解
HTH,
Berryl
<Window.InputBindings>
<cmdRef:KeyBindingEx CommandReference="{Binding AddCommand}"/>
</Window.InputBindings>
public class KeyBindingEx : KeyBinding
{
public static readonly DependencyProperty CommandReferenceProperty = DependencyProperty
.Register("CommandReference", typeof(CommandReference), typeof(KeyBindingEx),
new PropertyMetadata(OnCommandReferenceChanged));
private static void OnCommandReferenceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var kb = (KeyBinding) d;
var cmdRef = e.NewValue as VmCommand;
if(cmdRef==null) return;
kb.Key = cmdRef.GestureKey;
kb.Modifiers = cmdRef.GestureModifier;
kb.Command = cmdRef;
}
public CommandReference CommandReference
{
get { return (CommandReference)GetValue(CommandReferenceProperty); }
set { SetValue(CommandReferenceProperty, value); }
}
}
公共類CommandReference:PropertyChangedBase {...
public Key GestureKey
{
get { return _gestureKey; }
set
{
if (_gestureKey == value) return;
_gestureKey = value;
NotifyOfPropertyChange(() => GestureKey);
}
}
private Key _gestureKey;
}
/// <summary>A command whose primary purpose is to relay its functionality to other objects by invoking delegates.</summary>
public class VmCommand : CommandReference, ICommand
{
...
/// <summary>Action to be called when the Execute method of the command gets called</summary>
public Action ExecuteDelegate { get; protected set; }
/// <summary>Predicate to execute when the CanExecute of the command gets called (default is <c>true</c>)</summary>
public Func<bool> CanExecuteDelegate { get; protected set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.