我已經通過其他幾個有關WPF和焦點的帖子,最好的我可以確定我的代碼中缺少的東西。我正在使用嚴格的MVVM開發應用程序,所以我試圖避免在視圖文件中使用任何代碼隱藏(當需要隱藏代碼時使用附加行爲),但是在這一點上,即使將焦點代碼放在代碼隱藏文件中,視圖背後它不起作用。WPF焦點,不能同時獲得邏輯和鍵盤焦點
我有一個主窗口的應用程序,我試圖讓一個搜索窗口彈出一個熱鍵。我想只要用戶點擊熱鍵,鍵盤焦點就在搜索文本上,所以它只是熱鍵,然後輸入搜索詞。儘管鍵盤聲稱專注於元素,但除了邏輯焦點以外的所有內容都在工作。
我似乎無法從代碼中同時獲取鍵盤和邏輯焦點。但是,如果我在搜索框出現後立即點擊Tab,我會將其放入文本框中。
主窗口代碼:
<ribbon:RibbonWindow x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:attached="clr-namespace:UserInterface.Attached"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"
xmlns:viewModels="clr-namespace:UserInterface.ViewModels"
xmlns:views="clr-namespace:UserInterface.Views"
xmlns:layout="clr-namespace:UserInterface.ViewModels.Layout"
xmlns:layout1="clr-namespace:UserInterface.Views.Layout"
MinHeight="560"
MinWidth="950"
WindowStartupLocation="CenterScreen"
Icon="{Binding Layout.IconPath}"
DataContext="{Binding Main, Source={StaticResource Locator}}"
FocusManager.FocusedElement="{Binding ElementName=LayoutControl}"
Title="{Binding Layout.Title}">
<!-- Ribbon menu shortcuts -->
<Window.InputBindings>
<KeyBinding Modifiers="Control" Key="T" Command="{Binding Layout.Commands[GlobalObjectSearch]}" />
</Window.InputBindings>
<Grid>
<ContentPresenter Content="{Binding Layout}" x:Name="LayoutControl">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type layout:MainViewModel}">
<layout1:MainView/>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</ribbon:RibbonWindow>
代碼,以使搜索窗口顯示:
public SelfClosingDialogView ShowSelfClosingDialog(IWindowDialogViewModel dataContext)
{
dataContext.CheckWhetherArgumentIsNull(nameof(dataContext));
var view = new SelfClosingDialogView
{
DataContext = dataContext,
Owner = Application.Current?.MainWindow
};
view.Show();
return view;
}
搜索窗口代碼(重複使用,所以通用):
<Window x:Class="UserInterface.Views.DialogViews.SelfClosingDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:attached="clr-namespace:UserInterface.Attached"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
SizeToContent="WidthAndHeight"
WindowStyle="None"
WindowStartupLocation="CenterOwner">
<!-- Allow view models to cause the window to close -->
<Window.Style>
<Style TargetType="{x:Type Window}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsClosed}" Value="true">
<!-- Executes close -->
<Setter Property="attached:WindowCloseBehavior.Close" Value="true" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Style>
<!-- Displays the passed-in view model -->
<Grid>
<ContentPresenter x:Name="DialogPresenter" Content="{Binding}" Margin="0" />
</Grid>
</Window>
代碼爲我的搜索查看:
<UserControl x:Class="UserInterface.Views.DialogViews.ObjectSearchView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dialogViewModels="clr-namespace:UserInterface.ViewModels.DialogViewModels"
xmlns:utils="clr-namespace:WPF.Utils"
xmlns:attached="clr-namespace:UserInterface.Attached"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance dialogViewModels:ObjectSearchViewModel}"
MinWidth="250"
Focusable="True"
FocusManager.IsFocusScope="True">
<UserControl.InputBindings>
<KeyBinding Key="Enter" Command="{Binding BrowseToObjectCommand}" />
<KeyBinding Key="Escape" Command="{Binding CloseWindowCommand}" />
</UserControl.InputBindings>
<UserControl.Resources>
<Style BasedOn="{StaticResource FormTextBlockStyle}" TargetType="TextBlock" />
</UserControl.Resources>
<StackPanel>
<TextBox Name="SearchText"
Focusable="True"
Text="{utils:ValidatingLiveBinding SearchText}"
attached:NavigatingListBoxBehavior.LinkedListBox="{Binding ElementName=SearchResults}">
</TextBox>
<ScrollViewer HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Auto"
MaxHeight="400">
<ListBox Name="SearchResults"
ItemsSource="{Binding SearchResults}"
SelectedItem="{Binding SelectedSearchItem}"
Visibility="{Binding HasSearchResults, Converter={StaticResource BooleanToVisibilityConverter}}"
attached:ItemsControlProperties.DoubleClickCommand="{Binding BrowseToObjectCommand}"
KeyboardNavigation.IsTabStop="False"
IsSynchronizedWithCurrentItem="True" />
</ScrollViewer>
</StackPanel>
</UserControl>
最後,代碼隱藏砍我想嘗試獲得焦點(加調試代碼,這樣我不會失去焦點來回切換到Visual Studio):
public partial class ObjectSearchView : UserControl
{
public ObjectSearchView()
{
InitializeComponent();
this.Loaded += this.OnLoad;
}
private void OnLoad(object sender, RoutedEventArgs e)
{
this.PrintFocusInfo();
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(this), this.SearchText);
this.PrintFocusInfo();
this.SearchText.Focus();
this.PrintFocusInfo();
Keyboard.Focus(this.SearchText);
this.PrintFocusInfo();
}
[Conditional("DEBUG")]
private void PrintFocusInfo()
{
var logicalElement = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this.SearchText));
Debug.WriteLine("Current logical focus is on '{0}', of type '{1}' ({2})".FormatInvariantCulture((logicalElement as FrameworkElement)?.Name, logicalElement?.GetType().Name, logicalElement));
var focusedElement = Keyboard.FocusedElement;
Debug.WriteLine(
"Current Keyboard Focus is on '{0}', of type '{1}' ({2})".FormatInvariantCulture(
(focusedElement as FrameworkElement)?.Name,
focusedElement.GetType().Name,
focusedElement));
}
}
輸出窗口內容:
Current logical focus is on '', of type ''()
Current Keyboard Focus is on '', of type 'MainWindow' (UserInterface.Views.MainWindow)
Current logical focus is on '', of type ''()
Current Keyboard Focus is on '', of type 'MainWindow' (UserInterface.Views.MainWindow)
Current logical focus is on '', of type ''()
Current Keyboard Focus is on 'SearchText', of type 'TextBox' (System.Windows.Controls.TextBox)
Current logical focus is on '', of type ''()
Current Keyboard Focus is on 'SearchText', of type 'TextBox' (System.Windows.Controls.TextBox)
我一直在努力,包括一切我能想到的,但我不能讓邏輯焦點顯示,除了空什麼。