In This Article

Inline Editing

Items support inline editing, which means that a special UI mode can be entered where their text or other properties are in an editable state.

Starting Editing

If an item is editable (see below for how to provide this), pressing F2 while it is focused, or single tapping on an EditableContentControl in the item's template will trigger edit mode. This is often kept in sync with an item's IsEditing property.

Note

When edit mode is active, no arrow key-based item navigation will be enabled. Therefore, it is important to only mark items as editable (see below) that have a control in the item template that will respond to IsEditing property changes (from F2 pressed or the item is single tapped) and that also exits the edit mode when appropriate (i.e., focus loss). The default implementation of EditableContentControl does all this for you if you two-way bind its IsEditing property. If you wish to manage the IsEditing state on your own, do not mark the item as editable.

Selecting EditableContentControl TextBox Text

The default EditableContentControl template uses a TextBox when in edit mode. The virtual EditableContentControl.SelectText method is called as edit mode is entered, with its default implementation set to select all the text.

This method can be overridden to select a certain range of text instead. A common scenario is when editing filenames, to only select the actual name (without extension) portion of the filename.

Handling EditableContentControl Edited Text

When a value being edited in an EditableContentControl is committed, the virtual SetContentAfterEditing method is called and the edited content is passed in. The default implementation of this method simply sets the Content property to the specified edited content.

This method can be overridden to coerce the edited content as needed. Or if the edited content is invalid, you could choose not to call the base method, which would effectively cancel the edit. If you wish to keep edit mode active, set the IsEditing property back to true. This is sometimes done if there is an invalid value.

Using an Editable Item Template

When an item's text should be editable, use a EditableContentControl in its item template instead of a TextBlock to display the text. The text will display like a normal TextBlock by default but will switch to a TextBox for editing when in edit mode.

Here's an example of a DataTemplate that includes a Image and EditableContentControl. This example assumes that you are using an item type that has ImageSource, Name, and IsEditing properties. The IsEditing property has a two-way binding so that it can update the item's property as the end user exits edit mode.

<DataTemplate>
	<StackPanel Orientation="Horizontal">
		<Image Width="16" Height="16" Source="{Binding ImageSource}" Stretch="None" VerticalAlignment="Center" />
		<shared:EditableContentControl Margin="2,0,0,0" Content="{Binding Name, Mode=TwoWay}" IsEditing="{Binding IsEditing, Mode=TwoWay}" />
	</StackPanel>
</DataTemplate>

By specifying a ContentTemplate on the content control, you can surround the bound text content with other text. For instance, if Name has value "Foo", instead of just showing "Foo" in the item template, you could display the text as "Solution 'Foo'". Here's an example:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
		<Image Width="16" Height="16" Source="{Binding ImageSource}" Stretch="None" VerticalAlignment="Center" />
		<shared:EditableContentControl Margin="2,0,0,0" Content="{Binding Name, Mode=TwoWay}" IsEditing="{Binding IsEditing, Mode=TwoWay}">
			<shared:EditableContentControl.ContentTemplate>
				<DataTemplate>
					<StackPanel Orientation="Horizontal">
						<TextBlock Text="Solution '" VerticalAlignment="Center" />
						<TextBlock Text="{Binding}" VerticalAlignment="Center" />
						<TextBlock Text="'" VerticalAlignment="Center" />
					</StackPanel>
				</DataTemplate>
			</shared:EditableContentControl.ContentTemplate>
		</shared:EditableContentControl>
    </StackPanel>
</DataTemplate>

When an item with the above item template is edited, the surrounding "Solution '" and "'" text disappears and the TextBox occupies the entire space, editing the Name value.

Providing Whether an Item Is Editable

An item will only enter edit mode if the adapter returns that it is editable. The editable state is provided to the control by calls to the TreeListBoxItemAdapter.GetIsEditable method (via TreeListBox.ItemAdapter).

A Binding can be set in XAML to the TreeListBoxItemAdapter.IsEditableBinding property to tell how an item should retrieve the editable state. The GetIsEditable method will use that binding if it is supplied, and will otherwise return the TreeListBoxItemAdapter.IsEditableDefault property value. Please note that bindings aren't as performant as code, so for large trees or if you see performance issues, it is recommended to override the GetIsEditable method instead with custom logic to retrieve the appropriate value.

This example code shows how to override the method for a custom item type TreeNodeModel. This is not only the most performant way of providing a result, but also supports returning different results for different item types or based on item state.

public override bool GetIsEditing(object item) {
	var model = item as TreeNodeModel;
	return (model != null ? model.IsEditing : false);
}

Syncing Item Editing State

The control needs to two-way communicate with items regarding their editing state. This is accomplished by calls to the TreeListBoxItemAdapter.GetIsEditing and TreeListBoxItemAdapter.SetIsEditing methods (via TreeListBox.ItemAdapter).

A two-way Binding can be set in XAML to the TreeListBoxItemAdapter.IsEditingBinding property to tell how an item should retrieve the editable state. The GetIsEditing method will use that binding if it is supplied, and will otherwise return false. The SetIsEditing method will also use that binding if it is supplied. Please note that bindings aren't as performant as code, so for large trees or if you see performance issues, it is recommended to override the GetIsEditable and SetIsEditing methods instead with custom logic to retrieve/set the appropriate values.

The TreeListBoxItemAdapter.IsEditingPath property specifies the property name to watch for in case your item implements INotifyPropertyChanged. When a change to that property is detected, the updated value will be requested by the control. Note that even though a binding can be used via the IsEditingBinding property, for performance reasons, it is just used temporarily to get/set the value in the adapter methods' default implementations. The binding doesn't persist, and that's why the IsEditingPath property is required for property change notifications.

This example code shows how to override the methods for a custom item type TreeNodeModel. This is not only the most performant way of providing a result, but also supports returning different results for different item types or based on item state.

public override bool GetIsEditing(object item) {
	var model = item as TreeNodeModel;
	return (model != null ? model.IsEditing : false);
}

public override void SetIsEditing(object item, bool value) {
	var model = item as TreeNodeModel;
	if (model != null)
		model.IsEditing = value;
}