Welcome to MSDN Blogs Sign in | Join | Help

Implementing a "Insitu editor" using CIDER Adorner extensibility model.

Implementing a "Insitu" editor was so tough in Whidbey, but not in CIDER.  Lets see how its done for a button. When this button gets selected we want to pop-up a textbox on top of the text area of the button as follows

Editor1

Our Insitu textbox is an adorner that is provided for our "InsituButton". This adorner is provided by our custom AdornerProvider. Since we want to show our adorner when the button is the primary selection, we derive from the PrimarySelectionAdornerProvider as follows

    // 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:

Editor2

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:

editor3

When you drop in the "InsituButton" on the window, you want to specify that the "InsituButton" should provide the Insitu editor. This is done by adding an extension on top of the "InsituButton" as follows:

 

   [Extension(typeof(InSituAdornerProvider))]

    public class InSituButton : Button

    {

        public InSituButton() : base()

        {

            this.Content = "MyButton";

        }

    }

When this InsituButton is added to the Window, the Cider extensibility mechansim finds this extension and sees that it is a AdornerProvider which derives from the PrimarySelectionAdornerProvider. Hence it knows that whenever this control is in the primary selection, the adornerprovider should be instantiated.

Once the provider is instantiated, our custom code runs and adds the "Insitu" editor to the InsituButton. When the button looses the primary selection, the AdornerProvider is removed and so is our "adorner" (Insitu textbox).

Thats how simple it is to add "Insitu" editor to a control with CIDER extensibility.

 

Published Thursday, June 15, 2006 6:36 PM by subhagpo
Filed under:

Comments

# [WPF] Implémenter un éditeur "Insitu" en utilisant le modèle d'extensibilité Adorner de CIDER

Je relaie ici un article technique vraiment intéressant qui explique comment les développeurs peuvent...
Friday, June 16, 2006 5:17 AM by Thomas Lebrun
Anonymous comments are disabled
 
Page view tracker