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...