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);
}
精彩评论