2009-07-07 6 views
4

У меня есть DataGridTemplateColumn с DataTemplate как PasswordBox.Предупреждение о CapsLock

Я хочу предупредить пользователя, если CapsLock переключен.

private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) 
    { 
     if (Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled) 
     { 
     ... 

Теперь мне нужно поднять PopUp. Я не знаю, как это сделать. Помоги мне, пожалуйста.

Я пытался играть с подсказкой, как это:

((PasswordBox)sender).SetValue(ToolTipService.InitialShowDelayProperty, 1); 
((PasswordBox)sender).ToolTip = "CAPS LOCK"; 

Но это работает только тогда, когда курсор мыши находится там, и я нужен независимый Popup.

+0

@plotnick, комментируя на ваш вопрос, а не на мой ответ, чтобы вы его не пропустили, можете ли вы установить всплывающую подсказку в значение null для события LostFocus в PasswordBox (возможно, предварительно установите IsOpen в false)? (У меня нет WPF на моей машине для тестирования) –

ответ

9

Вы могли бы показать всплывающей подсказке

private void PasswordBox_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled) 
    { 
     ToolTip tt=new ToolTip(); 
     tt.Content="InValid"; 
     tt.Placement = PlacementMode.Custom; 
     PasswordBox.ToolTip=tt; 
     tt.IsOpen = true; 
    } 
    else 
    { 
     Passwordbox.ToolTip=null; 
    } 
} 
+0

Ой ... похоже, это идет для меня, но он по-прежнему открывает подсказку с курсором мыши. Мне нужна подсказка прямо под PasswordBox – Agzam

+0

tt.Placement = PlacementMode.Custom; Теперь это под PasswordBox – Agzam

+0

Патрик ... У меня другая проблема. ToolTip никуда не денется. Даже если PasswordBox теряет контроль. Как заставить его угасать? Я попытался убить его в случае с LostFocus, но то, что вы показали мне, рождает каждый раз новую подсказку ... – Agzam

0

Это полностью зависит от архитектуры, но простое решение:

Вы должны быть установки Dependency Property, которая будет наблюдаться на какой-то контроль на окно, которое станет видимым и будет отображать предупреждение для пользователя.

6

Я сделал предупреждение воздушный шар, чтобы решить Caps Lock предупреждения проблемы в моем WPF-проекта.

enter image description here

Если вы хотите добавить это предупреждение воздушного шара в вашем проекте, то выполните следующие действия:

- Добавить новое окно в вашем проекте и дать название «WarningBalloon».
- Добавьте следующий код XAML в новое окно и добавьте значок предупреждения в папку изображений проекта.

<Window x:Class="MyNameSpace.WarningBalloon" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Height="160" Width="469" WindowStyle="None" ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True" IsTabStop="False" OverridesDefaultStyle="False" AllowsTransparency="True" Background="Transparent" Opacity="1" > 
     <Grid Height="126" Width="453"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="81" /> 
       <RowDefinition Height="45*" /> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="177*" /> 
       <ColumnDefinition Width="72*" /> 
       <ColumnDefinition Width="0*" /> 
       <ColumnDefinition Width="170*" /> 
      </Grid.ColumnDefinitions> 
      <Border Margin="12,32,0,0" 
      CornerRadius="10,10,10,10" Grid.ColumnSpan="4" HorizontalAlignment="Left" Width="429" Height="82" VerticalAlignment="Top" Grid.RowSpan="2"> 
       <Border.Effect> 
        <DropShadowEffect 
       Color="#FF474747" /> 
       </Border.Effect> 
       <Border.Background> 
        <LinearGradientBrush 
       EndPoint="0.5,1" 
       StartPoint="0.5,0"> 
         <GradientStop 
       Color="#FF58C2FF" 
       Offset="0" /> 
         <GradientStop 
       Color="#FFFFFFFF" 
       Offset="1" /> 
        </LinearGradientBrush> 
       </Border.Background> 
       <Grid Height="76" Name="grid1" Width="441"> 
        <Image Height="35" HorizontalAlignment="Left" Margin="6,6,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="35" Source="/MyNameSpace;component/Images/warning-icon.png" /> 
        <Label Content="Caps Lock is ON" Height="31" HorizontalAlignment="Left" Margin="125,-6,0,0" Name="lblWarningHeader" VerticalAlignment="Top" FontSize="16" FontWeight="Bold" /> 
        <TextBlock HorizontalAlignment="Right" Margin="0,22,17,-1" Name="txbMessage" Width="379">Having Caps Lock on may cause you to enter your password incorrectly. <LineBreak/> <LineBreak/> You should press Caps Lock to turn it of before entering your password. VerticalAlignment="Top" Width="346" FontSize="11"</TextBlock> 
       </Grid> 
      </Border> 
      <Image 
      Source="{Binding Path=IconSource}" Width="16" HorizontalAlignment="Left" Margin="-56,0,0,-38" Height="16" VerticalAlignment="Bottom" Grid.Row="1" /> 
      <Path Data="M10402.99154,55.5381L10.9919,0.64 0.7,54.9" Fill="LightSkyBlue" HorizontalAlignment="Left" Margin="32,3,0,0" Stretch="Fill" Stroke="Black" Width="22" Height="31" VerticalAlignment="Top" /> 
     </Grid> 
    </Window> 

- Введите следующий код за LoginForm.

private Point location; 
    public static bool balloonVisFlag = false; 
    private DispatcherTimer timer; 
    WarningBalloon Balloon = null; 

    private void ShowHideBalloon() 
    {    
     if (System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock)) 
     { 
      if (timer == null) 
      { 
       timer = new DispatcherTimer(); 
      } 
      location = GetControlPosition(psbPassword); 
      Balloon.Left = location.X; 
      Balloon.Top = location.Y; 
      Balloon.Show(); 
      balloonVisFlag = true; 
      timer.Interval = TimeSpan.FromMilliseconds(5000); 
      timer.IsEnabled = true; 
      timer.Tick += new EventHandler(Timer_Tick); 
      psbPassword.Focus(); 
     } 
     else 
     { 
      Balloon.Hide(); 
      balloonVisFlag = false; 
      psbPassword.Focus(); 
     } 
    } 

    Point GetControlPosition(Control myControl) 
    { 
     Point locationToScreen = myControl.PointToScreen(new Point(0, 0)); 
     PresentationSource source = PresentationSource.FromVisual(myControl); 
     return source.CompositionTarget.TransformFromDevice.Transform(locationToScreen); 
    }  

    private void psbPassword_KeyDown(object sender, KeyEventArgs e) 
    { 
     ShowHideBalloon(); 
    } 

    private void Window_LocationChanged(object sender, EventArgs e) 
    { 
     if (balloonVisFlag == true) 
     { 
      ShowHideBalloon(); 
     } 
    } 

    private void Timer_Tick(object sender, EventArgs e) 
    { 
     if (balloonVisFlag == true) 
     { 
      Balloon.Hide(); 
      balloonVisFlag = false; 
     } 
    }  
} 
4

Мое решение немного другое. Я сделал ContentControl, вы можете положить что-нибудь внутри, и он уведомит статус блокировки. Добавьте этот класс в свой код.

public sealed class ShowCapLock : ContentControl 
    { 
    public bool ShowMessage 
    { 
     get { return (bool)GetValue(ShowMessageProperty); } 
     set { SetValue(ShowMessageProperty, value); } 
    } 
    public static readonly DependencyProperty ShowMessageProperty = 
     DependencyProperty.Register("ShowMessage", typeof(bool), typeof(ShowCapLock), new PropertyMetadata(false)); 

    static ShowCapLock() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ShowCapLock), new FrameworkPropertyMetadata(typeof(ShowCapLock))); 
    } 

    public ShowCapLock() 
    { 
     IsKeyboardFocusWithinChanged += (s,e) => RecomputeShowMessage(); 
     PreviewKeyDown += (s,e)=> RecomputeShowMessage(); 
     PreviewKeyUp += (s,e)=> RecomputeShowMessage(); 
    } 

    private void RecomputeShowMessage() 
    { 
     ShowMessage = IsKeyboardFocusWithin && System.Console.CapsLock; 
    } 
    } 

И добавить XAML к вашему Generic.xaml

<Style TargetType="{x:Type controls1:ShowCapLock}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type controls1:ShowCapLock}"> 
       <Grid> 
        <ContentPresenter Name="Presenter"/> 
        <Popup Placement="Bottom" PlacementTarget="{Binding ElementName=Presenter}" 
          IsOpen="{TemplateBinding ShowMessage}"> 
         <Border Background="LightGoldenrodYellow" BorderThickness="1" BorderBrush="Black"> 
          <TextBlock Foreground="Black"> 
           <TextBlock>Caps Lock is down.</TextBlock> 
          </TextBlock> 
         </Border> 
        </Popup> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

И вы можете положить немного контроль вокруг все, что вы хотите, чтобы оповещать для Caps Lock:

  <controls:ShowCapLock Grid.Row="5" Grid.Column="1"> 
       <PasswordBox . . ./> 
      </controls:ShowCapLock> 

 Смежные вопросы

  • Нет связанных вопросов^_^