Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
Hello,
 
there is a known bug with the WPF PasswordBox and touch devices (does not pop up virtual keyboard).
 
So I made an own usercontrol.
It has a PasswordBox and a TextBox, both on same position, TextBox has Opacity 0.
When the textbox gets the focus, it pops up the virtual keyboard, then gives to focus to the PasswordBox:
 
private void Text_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    CustomPasswordBox.Focus();
    SetSelection(CustomPasswordBox, currentCaretIndex, 0);
}
 
That is working perfect.
 
The textbox gets all input events from the mouse.
So I need to set the cursor position, selection etc. manually.
 
I found one problem with this, I have no idea why.
 
//Cursor-Position
private int currentCaretIndex = 0;
 
This currentCaretIndex should save my cursor position.
 
The following code should set the selection to my CustomPasswordBox,
when using mouse on the CustomTextBox.
 
But it is not working, when I try to click behind the last character,
it is one position before the last character. When adding +1 to it,
I cannot click left of the first character anymore.
 
It seems CustomTextBox.GetCharacterIndexFromPoint is returning wrong values somehow in that cases. Any idea to fix that? Thanks a lot!
 

//
        private void SetSelection(PasswordBox passwordBox, int start, int length)
        {
            if (start >= 0 && length <= passwordBox.Password.Length)
            {
                passwordBox.GetType().GetMethod("Select", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(passwordBox, new object[] { start, length });
            }
        }
 
        private int CalculatePosition(Point mousePoint)
        {
            //CaretIndex -> Cursor Position calculate
            CustomTextBox.Text = "";
            for (int i = 0; i < CustomPasswordBox.Password.Length; i++)
            {
                CustomTextBox.Text += CustomPasswordBox.PasswordChar;
            }
            return CustomTextBox.GetCharacterIndexFromPoint(mousePoint, true);
        }
 
        private void CustomTextBox_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            //CaretIndex -> Cursor Position calculate 
            Point mousePos = new Point(e.GetPosition(CustomTextBox).X, e.GetPosition(CustomTextBox).Y);
            currentCaretIndex = CalculatePosition(mousePos);
            //            //if (currentCaretIndex > 0)
            //    currentCaretIndex++;

            selectionStart = currentCaretIndex;
            isMouseDown = true; 
        }
 
        private void CustomTextBox_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (!isMouseDown)
            {
                return;
            }
 
            Point mousePos = new Point(e.GetPosition(CustomTextBox).X, e.GetPosition(CustomTextBox).Y);
            selectionEnd = CalculatePosition(mousePos);
            SetSelection(CustomPasswordBox, System.Math.Min(selectionStart, selectionEnd), System.Math.Max(selectionStart, selectionEnd));
        }
 
        private void CustomTextBox_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            isMouseDown = false;
        }
Posted 2-Jul-12 6:22am
EriBeh475
Edited 2-Jul-12 6:24am
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Since TextBox.GetCharacterIndexFromPoint always seems to return a position before a character, and not a psoition behind a cahracter, even if you click right of the latest character, it could be a solution to calculate myself if the position is right of the last char:
 
if (mousePoint.X > CustomPasswordBox.Password.Length * CustomPasswordBox.FontSize)
{
    return CustomPasswordBox.Password.Length;
}
else
{
    return CustomTextBox.GetCharacterIndexFromPoint(mousePoint, true);
}
 
This seems to be the solution! But it is not working well, you must click a long distance right of the last char, then it is working. If you only click a bit right of it, the cursor jumps before the last char...
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Found the solution.
Thanks for your interest.
 
SizeF size;
using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1)))
{
    size = graphics.MeasureString(CustomTextBox.Text, new Font(CustomTextBox.FontFamily.ToString(), Convert.ToSingle(CustomTextBox.FontSize), System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel));
}
 
if (mousePoint.X >= size.Width)
{
    return CustomPasswordBox.Password.Length;
}
else
{
    return CustomTextBox.GetCharacterIndexFromPoint(mousePoint, true);
}
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 390
1 Sergey Alexandrovich Kryukov 329
2 BillWoodruff 210
3 Afzaal Ahmad Zeeshan 204
4 CPallini 185
0 OriginalGriff 5,515
1 DamithSL 4,451
2 Maciej Los 3,902
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,175


Advertise | Privacy | Mobile
Web01 | 2.8.141216.1 | Last Updated 3 Jul 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100