How to: Create a ListView with Editable Cells

В этом примере демонстрируется создание элемента управления ListView в режиме представления GridView, который имеет редактируемые ячейки.

Пример

Для редактирования ячеек GridViewColumn в GridView следует определить пользовательский элемент управления для использования в качестве CellTemplate столбца.

В следующем примере показан пользовательский элемент управления с именем EditBox, который реализует два свойства зависимостей — Value и IsEditing.Свойство Value хранит значение ячейки.Свойство IsEditing определяет, является ли ячейка в настоящее время редактируемой.

    Public Class EditBox
        Inherits Control


...


        Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Object), GetType(EditBox), New FrameworkPropertyMetadata(Nothing))


...


        Public Shared IsEditingProperty As DependencyProperty = DependencyProperty.Register("IsEditing", GetType(Boolean), GetType(EditBox), New FrameworkPropertyMetadata(False))


...


    End Class
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));


...


}

В следующем примере создается Style для элемента управления EditBox.

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

Чтобы создать элемент управления TextBox для редактирования ячейки, следует реализовать Adorner.В следующем примере показан конструктор для EditBoxAdorner.

    Friend NotInheritable Class EditBoxAdorner
        Inherits Adorner


...


        Public Sub New(ByVal adornedElement As UIElement, ByVal adorningElement As UIElement)
            MyBase.New(adornedElement)
            _textBox = TryCast(adorningElement, TextBox)
            Debug.Assert(_textBox IsNot Nothing, "No TextBox!")

            _visualChildren = New VisualCollection(Me)

            BuildTextBox()
        End Sub


...


    End Class
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();
}


...


}

Для определения того, является ли EditBox редактируемым, используйте такие события, как MouseUp, MouseLeave и MouseEnter.Следующий пример показывает, как первое событие MouseUp, получаемое с помощью EditBox, выбирает EditBox, а второе событие MouseUp переводит EditBox в режим редактирования.

    Public Class EditBox
        Inherits Control


...


        Protected Overrides Sub OnMouseUp(ByVal e As MouseButtonEventArgs)
            MyBase.OnMouseUp(e)

            If e.ChangedButton = MouseButton.Right OrElse e.ChangedButton = MouseButton.Middle Then
                Return
            End If

            If Not IsEditing Then
                If (Not e.Handled) AndAlso (_canBeEdit OrElse _isMouseWithinScope) Then
                    IsEditing = True
                End If

                'If the first MouseUp event selects the parent ListViewItem,
                'then the second MouseUp event puts the EditBox in editing 
                'mode
                If IsParentSelected Then
                    _isMouseWithinScope = True
                End If
            End If
        End Sub


...


    End Class
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;
    }
}


...


}

В следующем примере показано, как использовать события MouseEnter и MouseLeave, чтобы определить, является ли ячейка редактируемой.

    Public Class EditBox
        Inherits Control


...


        Protected Overrides Sub OnMouseEnter(ByVal e As MouseEventArgs)
            MyBase.OnMouseEnter(e)
            If (Not IsEditing) AndAlso IsParentSelected Then
                _canBeEdit = True
            End If
        End Sub


...


        Protected Overrides Sub OnMouseLeave(ByVal e As MouseEventArgs)
            MyBase.OnMouseLeave(e)
            _isMouseWithinScope = False
            _canBeEdit = False
        End Sub


...


    End Class
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;
}


...


}

Чтобы определить GridViewColumn, позволяющий редактирование, задайте свойству CellTemplate элемент управления EditBox.В следующем примере свойство CellTemplate из GridViewColumn задается в качестве элемента управления EditBox.

<GridViewColumn Header="ID" Width="50" >
  <GridViewColumn.CellTemplate>
    <DataTemplate>
      <l:EditBox Height="25" Value="{Binding Path=EmployeeNumber}" />
    </DataTemplate>
  </GridViewColumn.CellTemplate>
</GridViewColumn>

См. также

Ссылки

Control

ListView

GridView

Основные понятия

Общие сведения о GridView

Другие ресурсы

Практические руководства, посвященные ListView