// Insitu AdornerProvider.
class InSituAdornerProvider : PrimarySelectionAdornerProvider
{
private MyTextBox _inSitu; //insitu editor
private AdornerPanel _panel; //the parent adorner panel
private ShowInSituEditorTask _myTask; //the task that enables the insitu editor
public InSituAdornerProvider()
{
_panel = new AdornerPanel();
_panel.IsContentFocusable = true;
_inSitu = new MyTextBox(_panel);
//Add a textbox but initially its hidden.
_inSitu.Enabled = false;
_panel.Children.Add(_inSitu);
//Add our task which will show the TextBox on doubleclick
_myTask = new ShowInSituEditorTask(_inSitu);
AdornerPanel.SetTask(_inSitu, _myTask);
Adorners.Add(_panel);
}
protected override void Activate(System.Windows.Design.Model.ModelItem item, UIElement view)
{
base.Activate(item, view);
_myTask.Item = item;
}
}
The ShowInSituEditorTask task is responsible to add a new ToolCommand and listen for the double click on the left mouse button and enable our Insitu editor. The editor (textbox) itself listens for the KeyDown event and deactivates the task when "enter" key is pressed. The code for our custom task looks like follows
class ShowInSituEditorTask : Task {
private MyTextBox _inSituEditor; // actual editor
private ModelItem _item; // model item
// The actual model item representing the "button"
// This is required to change the "text" property.
public ModelItem Item {
get {
return _item;
}
set {
_item = value;
}
}
// Constructor for our task.
public ShowInSituEditorTask(MyTextBox edit) {
_inSituEditor = edit;
// Create our new custom command
ToolCommand command = new ToolCommand("InSitu");
// Add our command to the InputBinding
InputBindings.Add(new InputBinding(command, new ToolGesture(ToolAction.DoubleClick, MouseButton.Left)));
// Associate our ToolCommand with the command handler.
ToolCommandBindings.Add(new ToolCommandBinding(command, EnableInSituEditor));
//Listen to the "Enter Key on the Text"
_inSituEditor.KeyDown += new KeyEventHandler(_inSituEditor_KeyDown);
}
//Listen for Enter key to deactivate the "insitu editor"
//by de-activating the task.
void _inSituEditor_KeyDown(object sender, KeyEventArgs e)
{
MyTextBox edit = sender as MyTextBox;
if (edit != null) {
if (e.Key == Key.Enter){
this.Deactivate();
}
}
}
//Enable the insitu editor on "doubleclick"
private void EnableInSituEditor(object sender, ExecutedToolEventArgs args)
{
//Enable the Editor
_inSituEditor.Enabled = true;
}
//when the task is de-activated set the Content property
//on the button to the text of the Insitu textBox.
protected override void OnDeactivated(EventArgs e)
{
Item.Properties["Content"].SetValue(_inSituEditor.Text);
//Disable the Editor
_inSituEditor.Enabled = false;
base.OnDeactivated(e);
}
}
So when our "fancy button" is selected and the user double clicks the "grey" text area, the editor is now enabled and looks like following:
The insitu editor itself is also a custom textbox which overrides the "ArrangeOverride" to position the editor right on the top of the button's text when its selected. The "MeasureOverride" causes the textbox to be of the exact size of the "text' being added. This allows the text editor to grow or shrink when the text is changed as shown in the figure below: