Share via


How to: Create a ListView with Editable Cells

この例では、編集可能なセルを含む ListView コントロールを GridView 表示モードで作成する方法を示します。

使用例

GridViewGridViewColumn のセルを編集するには、列の CellTemplate として使用するカスタム コントロールを定義します。

次の例では、EditBox という名前のカスタム コントロールを示します。このコントロールは、Value と IsEditing という 2 つの依存関係プロパティを実装しています。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));


...


}

次の例では、EditBox コントロールの Style を作成します。

<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 が編集可能になったかどうかを制御するには、MouseUpMouseLeaveMouseEnter などのイベントを使用します。次の例では、EditBox が受け取る最初の MouseUp イベントで EditBox を選択し、2 番目の 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 コントロールを設定します。次の例では、GridViewColumnCellTemplate プロパティを 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 に関する「方法」トピック