2014-01-24 56 views
4

我呈現出MessageBox並希望用戶能夠複製使用CTRL +ç消息的內容。問題是我似乎無法將焦點放在對話框上。焦點設置到一個用戶控件時,它是可見

MessageBox在MVVM中實現。爲了顯示它,我只需使用戶控件可見(中心屏幕)並禁用主視圖。

複製命令是使用實施了棱鏡DelegateCommand:到消息框上的按鈕CopyCommand火災

<UserControl.InputBindings> 
    <KeyBinding Key="C" Modifiers="Control" Command="{Binding CopyCommand}"/> 
</UserControl.InputBindings> 

如果我標籤。但是,當顯示對話框時,我無法讓它開始工作。

如何讓usercontrol接受焦點或將KeyBinding附加到整個usercontrol?

Note:我需要一個MVVM解決方案,因爲不想在代碼後面的任何代碼文件。

回答

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

+0

感謝您分享。這裏有很多解決方案,只有在控件已經可見時才能工作,或者在這種情況下間歇性地失敗。 –

相關問題