How to: Create a ListView with Editable Cells
This example shows how to create a ListView control in a GridView view mode that has editable cells.
Example
To edit the cells of a GridViewColumn in a GridView, define a custom control to use as the CellTemplate of the column.
The following example shows a custom control that is named EditBox
, which implements two dependency properties, Value
and IsEditing
. The Value
property stores the value of a cell. The IsEditing
property specifies whether the cell is currently editable.
public class EditBox : Control
{
...
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value",
typeof(object),
typeof(EditBox),
new FrameworkPropertyMetadata(null));
...
public static DependencyProperty IsEditingProperty =
DependencyProperty.Register(
"IsEditing",
typeof(bool),
typeof(EditBox),
new FrameworkPropertyMetadata(false));
...
}
The following example creates a Style for the EditBox
control.
<Style x:Key="{x:Type l:EditBox}" TargetType="{x:Type l:EditBox}" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:EditBox}">
<TextBlock x:Name="PART_TextBlockPart"
Text="{Binding Path=Value,RelativeSource =
{RelativeSource TemplatedParent}}">
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To create a TextBox control to edit a cell, implement an Adorner. The following example shows the constructor for the EditBoxAdorner
.
internal sealed class EditBoxAdorner : Adorner
{
...
public EditBoxAdorner(UIElement adornedElement,
UIElement adorningElement): base(adornedElement)
{
_textBox = adorningElement as TextBox;
Debug.Assert(_textBox != null, "No TextBox!");
_visualChildren = new VisualCollection(this);
BuildTextBox();
}
...
}
To control when the EditBox
is editable, use events like MouseUp, MouseLeave, or MouseEnter. The following example shows how the first MouseUp event that is received by an EditBox
selects the EditBox
, and the second MouseUp event puts the EditBox
in editing mode.
public class EditBox : Control
{
...
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
if (e.ChangedButton == MouseButton.Right ||
e.ChangedButton == MouseButton.Middle)
return;
if (!IsEditing)
{
if (!e.Handled && (_canBeEdit || _isMouseWithinScope))
{
IsEditing = true;
}
//If the first MouseUp event selects the parent ListViewItem,
//then the second MouseUp event puts the EditBox in editing
//mode
if (IsParentSelected)
_isMouseWithinScope = true;
}
}
...
}
The following example shows how you use the MouseEnter and MouseLeave events to determine if a cell is eligible for editing.
public class EditBox : Control
{
...
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
if (!IsEditing && IsParentSelected)
{
_canBeEdit = true;
}
}
...
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
_isMouseWithinScope = false;
_canBeEdit = false;
}
...
}
To define a GridViewColumn that permits editing, set the CellTemplate property to an EditBox
control. The following example specifies the CellTemplate property of a GridViewColumn as an EditBox
control.
<GridViewColumn Header="ID" Width="50" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<l:EditBox Height="25" Value="{Binding Path=EmployeeNumber}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
For the complete sample, see ListView with Editing Capability Sample.