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 5:22am
EriBeh472
Edited 2-Jul-12 5:24am
v2
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  
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  

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

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Sergey Alexandrovich Kryukov 515
1 OriginalGriff 468
2 Abhinav S 305
3 sanket saxena 295
4 Tadit Dash 160
0 Sergey Alexandrovich Kryukov 8,482
1 OriginalGriff 4,830
2 Peter Leow 3,794
3 Maciej Los 3,515
4 Er. Puneet Goel 3,107


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