views:

401

answers:

1

Hi,

I'm looking to create a WPF textbox control that acts similar to the email recipient textboxes in Outlook (the To, Cc and Bcc inputs). I don't necessarily care that much about auto-completion (i've found millions of examples for that), but what I'm really struggling with is how to have delimited text entries in the textbox behave as entities the way they do in Outlook (once a recipient you've entered resolves, that text becomes an 'entity' which you can click to select, right click to get a context menu, etc. it's not longer 'plain text' in which you can place your cursor)...

Does anyone have any high level ideas how to accomplish this? Know of any existing examples (I've googled for hours)?

Thanks so much in advance,

Michael.

+1  A: 

My rough thought process would be this... (note: I'm not actually coding it, so my details may be a little off...).

High level behaviour:

  • the type of data in your control is a list of items which aren't selectable. Therefore your control is, approximately, an ItemsControl (in terms of visual/XAML, it's an ItemsControl with a WrapPanel style layout and very simple TextBlock for the item template).
  • when your control gains focus, you need to switch the template to be a TextBox
  • when your control loses focus, you need to split the inputted text and convert it to a list for display.

Therefore, thinking code:

  • you need a UserControl, possibly derived from ItemsControl. That gives you basic behaviour to represent a list of items.
  • you need a custom DependencyProperty on your control that represents the delimited string.
  • when the string property changes, you need to parse it and replace the list of items in the control.
  • when the list property changes, you need to replace the string property with a suitably-delimited list.

In terms of code-behind, that part should be pretty simple. Then, for the XAML template...

  • you need a base template that displays your Items property as a list, using the WrapPanel layout mentioned above.
  • you need a trigger that replaces this template when the control has focus.
  • the replacement template should be a TextBox that is bound to the string property of the control.
  • the default binding behaviour on a TextBox will only push a new value when the TextBox loses focus, so you need to think about whether you want to make, say, an "Enter" keypress move focus (thus reverting the template to the list version - when the string property's value changes, your codebehind will update the list).

This should give you the basic behaviour. You should be able to bind either the list property or the string property from outside of the control, though you may have to be careful about what happens if you bind both properties since there's a two-way dependency between them...

Dan Puzey