开发者

Picking up value from wPF combo box when the mouse pointer or keyboard(arrow keys viz -> and <-) cursor is placed(C#3.0)

I have a开发者_Python百科 WPF combobox

<ComboBox Name="cmbExpression" IsEditable="True"/> 

Now I have written some text over there say fx(a,b,c) ,f(x),x,p,mv,P#,Fx(X),x,sometext

Now my requirement is that, whenever the cursor or the mouse (arrow keys viz -> and <-) will be placed on the characters, I should be able to get the value.

Some Test cases:

Case 1:

User put the cursor or mouse pointer on x of f(x).

Output will be f(x).

Case 2:

User put on v of mv

Output: mv

Case 3:

User put the cursor on t of sometext.

Output: sometext

Case 4:

User put the cursor on ( on Fx(X)

Output: Fx(X)

Case 5:

    User put the cursor on ',' of  fx(a,b,c) 

   Output: fx(a,b,c)

I am using C#3.0 and WPF

Help needed.

Thanks


TextBox has a method called GetCharacterIndexFromPoint which returns the character index at the supplied position, TextBlock has a similar method which returns a TextPointer. You can use these methods to find the what is under the cursor.

<ComboBox IsEditable="True" MouseMove="ComboBox_MouseMove" />

Code

private void ComboBox_MouseMove(object sender, MouseEventArgs e)
{
    var combobox = (ComboBox)sender;
    //An editable ComboBox uses a TextBox named PART_EditableTextBox 
    var textbox = (TextBox)combobox.Template.FindName("PART_EditableTextBox", combobox);

    var pos = textbox.GetCharacterIndexFromPoint(e.GetPosition(textbox),true);
    var text = textbox.Text;
    if (string.IsNullOrEmpty(text))
        return;

    txt.Text = GetWordAtPos(text,pos);
}

private static string GetWordAtPos(string str, int pos)
{
    Stack<char> matches = new Stack<char>();
    int wordStart = 0, wordEnd = 0;
    for (int i = 0; i < str.Length - 1 && wordEnd == 0; i++)
    {
        char c = str[i];

        switch (c)
        {
            case ',':
                if (matches.Count == 0)
                {
                    if (i > pos)
                        wordEnd = i;
                    else
                        wordStart = i;
                }
                break;
            case '(':
                matches.Push(')');
                break;
            case ')':
                if (matches.Count == 0 || matches.Peek() != c)
                    throw new ArgumentException("Found ) without matching ( character.");
                else
                    matches.Pop();
                break;
        }
    }

    string word;
    if (wordEnd == 0)
        word = str.Substring(wordStart);
    else
        word = str.Substring(wordStart, wordEnd - wordStart);

    return word.Trim(',');
}

A different approach you may want to look into if you need more control over the appearance of each token would be to generate a Run element for each token, but this seems to work well for the cases you described.


For Keyboard navigation(-> & <-)

private void comboBox1_KeyUp(object sender, KeyEventArgs e)
        {
            var combobox = (ComboBox)sender;
            //An editable ComboBox uses a TextBox named PART_EditableTextBox  
            var textbox = (TextBox)combobox.Template.FindName("PART_EditableTextBox", combobox);

             //This is the way of getting the charecter position
            **var pos = textbox.CaretIndex - 1;**

            var text = textbox.Text;
            if (string.IsNullOrEmpty(text))
                return;

            txt.Text = GetWordAtPos(text, pos); 
        } 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜