Вопрос

У меня есть DataGridTemplateColumn с DataTemplate в качестве пароля.

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

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

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

Я попытался поиграть с ToolTip вот так:

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

Но это работает только тогда, когда курсор мыши наведен на него, и мне нужно независимое всплывающее окно.

Это было полезно?

Решение

Вы можете показать всплывающую подсказку

private void PasswordBox_KeyDown(object sender, KeyEventArgs e)
{
    if ((Keyboard.GetKeyStates(Key.CapsLock) & KeyStates.Toggled) == KeyStates.Toggled)
    {
        if (PasswordBox.ToolTip == null)
        {
            ToolTip tt = new ToolTip();
            tt.Content = "Warning: CapsLock is on";
            tt.PlacementTarget = sender as UIElement;
            tt.Placement = PlacementMode.Bottom;
            PasswordBox.ToolTip = tt;
            tt.IsOpen = true;
        }
    }
    else
    {
        var currentToolTip = PasswordBox.ToolTip as ToolTip;
        if (currentToolTip != null)
        {
            currentToolTip.IsOpen = false;
        }

        PasswordBox.ToolTip = null;
    }
}

Другие советы

Я сделал всплывающее предупреждение для решения проблемы с предупреждением о 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>

- Введите следующий код позади формы входа.

    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;
        }
    }    
}

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

  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>

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top