当双击单元格时,停止进入编辑模式。

4

我有一个数据网格(DataGrid)。每行都有一个编辑按钮(Edit Button)。当用户点击这个编辑按钮时,该行的每个单元格都进入编辑模式。当我点击任何编辑按钮时,它的模板(template)会变成保存按钮(save button)。编辑完成后,我点击保存按钮(save button),数据网格行(DataGridRow)退出编辑模式,保存按钮再次变为编辑按钮。这很好地解决了问题。

以下是我的代码:

Xaml:

<DataGrid Grid.Column="1" Grid.Row="3"  AutoGenerateColumns="False" RowHeaderWidth="0" GridLinesVisibility="Vertical"
          ItemsSource="{Binding Source={StaticResource ItemsViewSource}}" SelectedItem="{Binding SelectedItem}"
          CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False"
          SelectionMode="Single" SelectionUnit="FullRow">

    <DataGrid.Columns>

        <DataGridTemplateColumn Header="Name of the Item" Width="*" SortDirection="Ascending">
            <DataGridTemplateColumn.HeaderStyle>
                <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
                    <Setter Property="HorizontalContentAlignment" Value="Left"/>
                </Style>
            </DataGridTemplateColumn.HeaderStyle>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" PreviewKeyDown="TextBox_PreviewKeyDown"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellStyle>
                <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridCell}">
                                <Grid Background="{TemplateBinding Background}">
                                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,0,0,0" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGridTemplateColumn.CellStyle>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Header="Edit" Width="50" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="Edit" Style="{StaticResource EditSaveButton}"  
                            Command="{Binding DataContext.EditItemCommand, 
                                              RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}" 
                            Click="EditButton_Click"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Header="Delete" Width="70" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="Delete" Style="{StaticResource DeleteButton}"
                            Command="{Binding DataContext.CancelItemEditOrDeleteCommand, 
                                              RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Page}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

    </DataGrid.Columns>

</DataGrid>

后台代码(cs):

void EditButton_Click(object sender, RoutedEventArgs e)
{
    int colIndex = 0;
    int rowIndex = 0;

    DependencyObject dep = (DependencyObject)e.OriginalSource;
    while (dep != null && !(dep is DataGridCell))
    {
        dep = VisualTreeHelper.GetParent(dep);
    }

    if (dep == null)
        return;
    DataGridRow row = null;
    if (dep is DataGridCell)
    {

        colIndex = ((DataGridCell)dep).Column.DisplayIndex;

        while (dep != null && !(dep is DataGridRow))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        row = (DataGridRow)dep;
        rowIndex = FindRowIndex(row);

    }

    while (dep != null && !(dep is DataGrid))
    {
        dep = VisualTreeHelper.GetParent(dep);
    }

    if (dep == null)
        return;

    DataGrid dg = (DataGrid)dep;
    if (row != null)
    {
        var rows = GetDataGridRows(dg);

        if (row.IsEditing)
        {
            dg.CommitEdit(DataGridEditingUnit.Row, true);

            foreach (DataGridRow r in rows)
            {
                r.IsEnabled = true;
            }
        }
        else
        {
            dg.CurrentCell = new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[0]);
            dg.BeginEdit();

            foreach (DataGridRow r in rows)
            {
                if (!(r.IsEditing))
                {
                    r.IsEnabled = false;
                }
            }
        }
    }
}

public DataGridCell GetDataGridCell(DataGridCellInfo cellInfo)
{
    var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
    if (cellContent != null)
        return (DataGridCell)cellContent.Parent;

    return null;
}

private int FindRowIndex(DataGridRow row)
{
    DataGrid dataGrid = ItemsControl.ItemsControlFromItemContainer(row) as DataGrid;

    int index = dataGrid.ItemContainerGenerator.IndexFromContainer(row);

    return index;
}

public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
    var itemsSource = grid.ItemsSource as IEnumerable;
    if (null == itemsSource) yield return null;
    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
        if (null != row) yield return row;
    }
}

基本上我有两个问题:
  1. 当我双击一个单元格时,该单元格会进入编辑模式。因为我已经提供了编辑按钮,所以我想停止这种行为。
  2. 一旦任何一行进入编辑模式,并且如果我更改该行的第一个单元格中的数据,现在如果我移动到下一个单元格,第一个单元格将更改其模板为cellTemplate。我不想改变它的模板。我的意思是,我希望它保持在它的cellEditTemplate中,直到我再次点击编辑按钮。
如果有人对其中任何一个问题有答案,请发表。
谢谢。

兽的数字诱惑我不要点赞 - Carbine
需要基督教背景才能理解这个笑话。 - Fratyx
@Fratyx 加油,我是一个不信任宗教的人。我相信人类。 - Vishal
@Fratyx 现在解释这个笑话给他已经没有意义了,他不是一个信徒,真可惜 :( - Carbine
1
但宗教总是适合用来开心一笑。 - Fratyx
显示剩余4条评论
2个回答

2

只需尝试类似以下操作:

void Cell_Click(object sender, RoutedEventArgs e){
(...)
e.Handled;
}

这将阻止进一步的事件回调。

此外,这个主题可能会有所帮助。


2

针对您的第二个问题,当单击编辑按钮时,为了使单元格始终可编辑,您可以将单元格模板设置为文本框而不是文本块,并在正常情况下使其只读。当行可编辑时,使文本框可编辑,这样它将保持编辑模式,即使您移动到下一个单元格。这也将解决您的第一个问题,即双击单元格进入编辑模式,因为文本框是只读的,除非用户按下编辑按钮,否则双击效果将对他无效,因此单元格不会进入编辑模式。


抱歉回复晚了,我没有注意到你的答复。我想问你一件事。你说我应该使用TextBox作为cellTemplate,但是我想展示Label或TextBlock作为cellTemplate,因为始终可见的TextBox看起来很丑。 - Vishal
如果您将Textbox作为单元格模板,则不会遇到多余的EditCellTemplate问题。而且,正如我之前所说,将其设置为只读默认值将禁用单元格的双击效果。您可以自行处理可编辑或只读行为。 - jadavparesh06
我想再问您一个问题:如果我有相同的场景,但是cellTemplate是TextBlock,而cellEditTemplate是ComboBox,那么您会如何处理这个问题? - Vishal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接