我正在显示MessageBox
并希望用户能够使用 CTRL + C 复制邮件内容。问题是我似乎无法将焦点设置到对话框中。
MessageBox
在MVVM中实现。为了显示它我只是使用户控件可见(中心屏幕)并禁用主视图。
使用Prism DelegateCommand实现复制命令:
<UserControl.InputBindings>
<KeyBinding Key="C" Modifiers="Control" Command="{Binding CopyCommand}"/>
</UserControl.InputBindings>
如果我选中了消息框按钮,则会触发CopyCommand。但是,当显示对话框时,我无法让它最初工作。
如何让usercontrol接受焦点或将KeyBinding附加到整个usercontrol?
Note:
我需要一个MVVM解决方案,因为不需要代码隐藏文件中的任何代码。
答案 0 :(得分:4)
在使用MVVM模式并需要与用户界面交互的情况下,我总是尝试通过附加行为来实现此解决方案。附加行为是非常强大且方便的解决方案,完全满足MVVM模式,也可以在Blend中使用(具有预定义的接口)。
在这种情况下,我创建了一个附加行为VisibleFocusBehavior
,它设置了一个IsVisibleChanged
事件处理程序,其中焦点是在元素可见性的情况下设置的。
为了避免出现虚线框,当控件获得焦点时,我为UserControl设置了FocusVisualStyle="{x:Null}
。
<强> VisibleFocusBehavior
强>
public class VisibleFocusBehavior
{
#region IsFocusEnabled Dependency Property
public static readonly DependencyProperty IsFocusEnabledProperty;
public static void SetIsFocusEnabled(DependencyObject DepObject, bool value)
{
DepObject.SetValue(IsFocusEnabledProperty, value);
}
public static bool GetIsFocusEnabled(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(IsFocusEnabledProperty);
}
#endregion
#region BringToFrontBehavior Constructor
static VisibleFocusBehavior()
{
IsFocusEnabledProperty = DependencyProperty.RegisterAttached("IsFocusEnabled",
typeof(bool),
typeof(VisibleFocusBehavior),
new UIPropertyMetadata(false, IsFocusTurn));
}
#endregion
#region IsFocusTurn
private static void IsFocusTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
UIElement element = sender as UIElement;
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
if (element != null)
{
element.IsVisibleChanged += new DependencyPropertyChangedEventHandler(ElementIsVisibleChanged);
}
}
}
#endregion
#region ElementIsVisibleChanged Handler
private static void ElementIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
UIElement visibilityElement = sender as UIElement;
if (visibilityElement.IsVisible == true)
{
visibilityElement.Focus();
}
}
#endregion
}
<强> Example of using
强>
<UserControl x:Class="UserControlFocusHelp.TestUserControl"
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:local="clr-namespace:UserControlFocusHelp"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
xmlns:AttachedBehaviors="clr-namespace:UserControlFocusHelp.AttachedBehaviors"
AttachedBehaviors:VisibleFocusBehavior.IsFocusEnabled="True"
FocusVisualStyle="{x:Null}">
<UserControl.InputBindings>
<KeyBinding Key="C"
Modifiers="Control"
Command="{Binding CopyCommand}" />
</UserControl.InputBindings>
<强> Test window
强>
XAML
<Grid>
<local:TestUserControl x:Name="TestUserControl"
Width="300"
Height="300"
Focusable="True"
Visibility="Collapsed" />
<Button Width="100"
Height="30"
Content="Visible"
HorizontalAlignment="Left"
Click="Button_Click" />
</Grid>
Code-behind
private void Button_Click(object sender, RoutedEventArgs e)
{
TestUserControl.Visibility = Visibility.Visible;
}
此link提供完整示例。
答案 1 :(得分:1)
有一种简单的方法可以将焦点设置到控件上。举个例子:
<UserControl
FocusManager.FocusedElement="{Binding ElementName=txtNickname}">
<Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox x:Name="txtNickname" Grid.Row="1" />
</Grid>
</Grid>