Получение значения из поля со списком wPF при наведении указателя мыши или клавиатуры (клавиши со стрелками, а именно -> и <-) (C # 3.0) - PullRequest
2 голосов
/ 20 августа 2010

У меня есть поле со списком WPF

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

Теперь я написал там какой-нибудь текст, скажем fx(a,b,c) ,f(x),x,p,mv,P#,Fx(X),x,sometext

Теперь мое требование заключается в том, чтобы всякий раз, когда на символы помещались курсор или мышь (клавиши со стрелками viz -> и <-) </strong>, я мог получить значение. Некоторые тестовые случаи:

Дело 1:

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

Output will be f(x).

Дело 2:

User put on v of mv

Output: mv

Дело 3:

User put the cursor on t of sometext.

Output: sometext

Дело 4:

User put the cursor on ( on Fx(X)

Output: Fx(X)

Дело 5:

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

   Output: fx(a,b,c)

Я использую C # 3.0 и WPF

Требуется помощь.

Спасибо

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

TextBox имеет метод с именем GetCharacterIndexFromPoint , который возвращает индекс символа в предоставленной позиции, TextBlock имеет аналогичный метод, который возвращает TextPointer. Вы можете использовать эти методы, чтобы найти то, что находится под курсором.

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

код

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(',');
}

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

1 голос
/ 30 августа 2010

Для навигации по клавиатуре (-> & <-) </p>

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); 
        } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...