检查 DataGrid 的单元格当前是否已编辑的代码

发布于 2024-09-09 06:51:52 字数 77 浏览 7 评论 0原文

是否有一个简单的可能性来检查DataGrid当前是否处于EditMode(无需订阅BeginningEdit和CellEditEnding)

Is there a simple possibility to check if the DataGrid is currently in EditMode (Without to subscribe to BeginningEdit and CellEditEnding)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南渊 2024-09-16 06:51:52

看来您也可以从项目视图中获取此信息,即这有效:

IEditableCollectionView itemsView = stateGrid.Items;
if (itemsView.IsAddingNew || itemsView.IsEditingItem)
{
    stateGrid.CommitEdit(DataGridEditingUnit.Row, true);
}

我尚未确认这一点,但如果您的绑定集合提供 IEditableCollectionView,您很可能可以在视图模型中获得这些标志。

It seems you can also get this information from the items view, namely this works:

IEditableCollectionView itemsView = stateGrid.Items;
if (itemsView.IsAddingNew || itemsView.IsEditingItem)
{
    stateGrid.CommitEdit(DataGridEditingUnit.Row, true);
}

I have not confirmed this but most likely you could get these flags in a viewmodel if your bound collection provides an IEditableCollectionView.

離人涙 2024-09-16 06:51:52

好吧,我还没有找到一个简单的解决方案,也没有人给我指出一个。以下代码可用于将附加属性 IsInEditMode 添加到 DataGrid。希望它对某人有帮助:

public class DataGridIsInEditModeTracker {

    public static bool GetIsInEditMode(DataGrid dataGrid) {
        return (bool)dataGrid.GetValue(IsInEditModeProperty);
    }

    private static void SetIsInEditMode(DataGrid dataGrid, bool value) {
        dataGrid.SetValue(IsInEditModePropertyKey, value);
    }

    private static readonly DependencyPropertyKey IsInEditModePropertyKey = DependencyProperty.RegisterAttachedReadOnly("IsInEditMode", typeof(bool), typeof(DataGridIsInEditModeTracker), new UIPropertyMetadata(false));

    public static readonly DependencyProperty IsInEditModeProperty = IsInEditModePropertyKey.DependencyProperty;


    public static bool GetProcessIsInEditMode(DataGrid dataGrid) {
        return (bool)dataGrid.GetValue(ProcessIsInEditModeProperty);
    }

    public static void SetProcessIsInEditMode(DataGrid dataGrid, bool value) {
        dataGrid.SetValue(ProcessIsInEditModeProperty, value);
    }


    public static readonly DependencyProperty ProcessIsInEditModeProperty =
        DependencyProperty.RegisterAttached("ProcessIsInEditMode", typeof(bool), typeof(DataGridIsInEditModeTracker), new FrameworkPropertyMetadata(false, delegate(DependencyObject d,DependencyPropertyChangedEventArgs e) {

            DataGrid dataGrid = d as DataGrid;
            if (null == dataGrid) {
                throw new InvalidOperationException("ProcessIsInEditMode can only be used with instances of the DataGrid-class");
            }
            if ((bool)e.NewValue) {
                dataGrid.BeginningEdit += new EventHandler<DataGridBeginningEditEventArgs>(dataGrid_BeginningEdit);
                dataGrid.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid_CellEditEnding);
            } else {
                dataGrid.BeginningEdit -= new EventHandler<DataGridBeginningEditEventArgs>(dataGrid_BeginningEdit);
                dataGrid.CellEditEnding -= new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid_CellEditEnding);
            }
        }));

    static void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {            
        SetIsInEditMode((DataGrid)sender,false);
    }

    static void dataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) {
        SetIsInEditMode((DataGrid)sender, true);
    }                  
}

要使用它,请将数据网格上的 ProcessIsInEditMode- 属性设置为 true:

<DataGrid local:DataGridIsInEditModeTracker.ProcessIsInEditMode="True" ..  other properties ..>

之后您将使 IsInEditMode- 属性与 DataGrid 的模式同步。
如果您还需要编辑单元,请相应地更改 BeginningEdit 中的代码。

Ok, I havent found a simple solution and no one pointed me to one. The following code can be used to add an attached property IsInEditMode to a DataGrid. Hope it helps someone:

public class DataGridIsInEditModeTracker {

    public static bool GetIsInEditMode(DataGrid dataGrid) {
        return (bool)dataGrid.GetValue(IsInEditModeProperty);
    }

    private static void SetIsInEditMode(DataGrid dataGrid, bool value) {
        dataGrid.SetValue(IsInEditModePropertyKey, value);
    }

    private static readonly DependencyPropertyKey IsInEditModePropertyKey = DependencyProperty.RegisterAttachedReadOnly("IsInEditMode", typeof(bool), typeof(DataGridIsInEditModeTracker), new UIPropertyMetadata(false));

    public static readonly DependencyProperty IsInEditModeProperty = IsInEditModePropertyKey.DependencyProperty;


    public static bool GetProcessIsInEditMode(DataGrid dataGrid) {
        return (bool)dataGrid.GetValue(ProcessIsInEditModeProperty);
    }

    public static void SetProcessIsInEditMode(DataGrid dataGrid, bool value) {
        dataGrid.SetValue(ProcessIsInEditModeProperty, value);
    }


    public static readonly DependencyProperty ProcessIsInEditModeProperty =
        DependencyProperty.RegisterAttached("ProcessIsInEditMode", typeof(bool), typeof(DataGridIsInEditModeTracker), new FrameworkPropertyMetadata(false, delegate(DependencyObject d,DependencyPropertyChangedEventArgs e) {

            DataGrid dataGrid = d as DataGrid;
            if (null == dataGrid) {
                throw new InvalidOperationException("ProcessIsInEditMode can only be used with instances of the DataGrid-class");
            }
            if ((bool)e.NewValue) {
                dataGrid.BeginningEdit += new EventHandler<DataGridBeginningEditEventArgs>(dataGrid_BeginningEdit);
                dataGrid.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid_CellEditEnding);
            } else {
                dataGrid.BeginningEdit -= new EventHandler<DataGridBeginningEditEventArgs>(dataGrid_BeginningEdit);
                dataGrid.CellEditEnding -= new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid_CellEditEnding);
            }
        }));

    static void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {            
        SetIsInEditMode((DataGrid)sender,false);
    }

    static void dataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) {
        SetIsInEditMode((DataGrid)sender, true);
    }                  
}

To use it, set on the datagrid the ProcessIsInEditMode- property to true:

<DataGrid local:DataGridIsInEditModeTracker.ProcessIsInEditMode="True" ..  other properties ..>

Afer that you will have the IsInEditMode-property in sync with the mode of the DataGrid.
If you want also the editing cell, change the code in BeginningEdit accoringly.

阪姬 2024-09-16 06:51:52

我找到了一个更短的解决方法(VB.NET/C#):VB.NET

C

<Extension>
Public Function GetContainerFromIndex(Of TContainer As DependencyObject) _
    (ByVal itemsControl As ItemsControl, ByVal index As Integer) As TContainer
  Return DirectCast(
    itemsControl.ItemContainerGenerator.ContainerFromIndex(index), TContainer)
End Function

<Extension>
Public Function IsEditing(ByVal dataGrid As DataGrid) As Boolean
  Return dataGrid.GetEditingRow IsNot Nothing
End Function

<Extension>
Public Function GetEditingRow(ByVal dataGrid As DataGrid) As DataGridRow
  Dim sIndex = dataGrid.SelectedIndex
  If sIndex >= 0 Then
    Dim selected = dataGrid.GetContainerFromIndex(Of DataGridRow)(sIndex)
    If selected.IsEditing Then Return selected
  End If

  For i = 0 To dataGrid.Items.Count - 1
    If i = sIndex Then Continue For
    Dim item = dataGrid.GetContainerFromIndex(Of DataGridRow)(i)
    If item.IsEditing Then Return item
  Next

  Return Nothing
End Function

#:

public static TContainer GetContainerFromIndex<TContainer>
  (this ItemsControl itemsControl, int index)
    where TContainer : DependencyObject
{
  return (TContainer)
    itemsControl.ItemContainerGenerator.ContainerFromIndex(index);
}

public static bool IsEditing(this DataGrid dataGrid)
{
  return dataGrid.GetEditingRow() != null;
}

public static DataGridRow GetEditingRow(this DataGrid dataGrid)
{
  var sIndex = dataGrid.SelectedIndex;
  if (sIndex >= 0)
  {
    var selected = dataGrid.GetContainerFromIndex<DataGridRow>(sIndex);
    if (selected.IsEditing) return selected;
  }

  for (int i = 0; i < dataGrid.Items.Count; i++)
  {
    if (i == sIndex) continue;
    var item = dataGrid.GetContainerFromIndex<DataGridRow>(i);
    if (item.IsEditing) return item;
  }

  return null;
}

I found a shorter workaround (VB.NET/C#):

VB.NET

<Extension>
Public Function GetContainerFromIndex(Of TContainer As DependencyObject) _
    (ByVal itemsControl As ItemsControl, ByVal index As Integer) As TContainer
  Return DirectCast(
    itemsControl.ItemContainerGenerator.ContainerFromIndex(index), TContainer)
End Function

<Extension>
Public Function IsEditing(ByVal dataGrid As DataGrid) As Boolean
  Return dataGrid.GetEditingRow IsNot Nothing
End Function

<Extension>
Public Function GetEditingRow(ByVal dataGrid As DataGrid) As DataGridRow
  Dim sIndex = dataGrid.SelectedIndex
  If sIndex >= 0 Then
    Dim selected = dataGrid.GetContainerFromIndex(Of DataGridRow)(sIndex)
    If selected.IsEditing Then Return selected
  End If

  For i = 0 To dataGrid.Items.Count - 1
    If i = sIndex Then Continue For
    Dim item = dataGrid.GetContainerFromIndex(Of DataGridRow)(i)
    If item.IsEditing Then Return item
  Next

  Return Nothing
End Function

C#:

public static TContainer GetContainerFromIndex<TContainer>
  (this ItemsControl itemsControl, int index)
    where TContainer : DependencyObject
{
  return (TContainer)
    itemsControl.ItemContainerGenerator.ContainerFromIndex(index);
}

public static bool IsEditing(this DataGrid dataGrid)
{
  return dataGrid.GetEditingRow() != null;
}

public static DataGridRow GetEditingRow(this DataGrid dataGrid)
{
  var sIndex = dataGrid.SelectedIndex;
  if (sIndex >= 0)
  {
    var selected = dataGrid.GetContainerFromIndex<DataGridRow>(sIndex);
    if (selected.IsEditing) return selected;
  }

  for (int i = 0; i < dataGrid.Items.Count; i++)
  {
    if (i == sIndex) continue;
    var item = dataGrid.GetContainerFromIndex<DataGridRow>(i);
    if (item.IsEditing) return item;
  }

  return null;
}
桃气十足 2024-09-16 06:51:52

上面使用 datagridrow 上的 IsEditing 或 IEditableCollectionView 上的 IsEdititngItem 的所有答案对我来说都是部分答案:

如果用户输入版本,然后在任何其他单元格上单击,则会触发 EndEdit 事件,但 DataGridRow 的 IsEditing 属性仍然为 True ! !如果您尝试找到负责的 DataGridCell,其 IsEditingProperty 始终为 false...
我认为这是一个错误。为了获得所需的行为,我必须编写这个丑陋的解决方法

Public Shared ReadOnly ForceEndEditProp As DependencyProperty =
        DependencyProperty.RegisterAttached("ForceEndEdit", GetType(Boolean),
        GetType(DataGridEditing), New PropertyMetadata(False, AddressOf ForceEndEditChanged))

Protected Shared Sub ForceEndEditChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    Dim g As DataGrid = TryCast(d, DataGrid)
    If g Is Nothing Then Return
    ''IsCommiting prevents a StackOverflow ...
    Dim IsCommiting As Boolean = False
    AddHandler g.CellEditEnding, Sub(s, e1)
                                     If IsCommiting Then Return
                                     IsCommiting = True
                                     g.CommitEdit(DataGridEditingUnit.Row, True)
                                     IsCommiting = False
                                 End Sub
End Sub

Public Shared Function GetForceEndEdit(o As DependencyObject) As Boolean
    Return o.GetValue(ForceEndEditProp)
End Function

Public Shared Sub SetForceEndEdit(ByVal o As DependencyObject, ByVal value As Boolean)
    o.SetValue(ForceEndEditProp, value)
End Sub

,这基本上会强制网格在任何单元格停止编辑时在 datagridrow 上设置 IsEditing = false 。

All the answers above using IsEditing on the datagridrow or IsEdititngItem on the IEditableCollectionView are partial answers to me :

If the user enter edition, then clics on any other cell, the EndEdit event is fired but the DataGridRow has still the property IsEditing to True !!! And if you try to find the DataGridCell responsible, its IsEditingProperty Is always false...
I think it's a bug. And to have the desired behaviour, I had to write this Ugly workaround

Public Shared ReadOnly ForceEndEditProp As DependencyProperty =
        DependencyProperty.RegisterAttached("ForceEndEdit", GetType(Boolean),
        GetType(DataGridEditing), New PropertyMetadata(False, AddressOf ForceEndEditChanged))

Protected Shared Sub ForceEndEditChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    Dim g As DataGrid = TryCast(d, DataGrid)
    If g Is Nothing Then Return
    ''IsCommiting prevents a StackOverflow ...
    Dim IsCommiting As Boolean = False
    AddHandler g.CellEditEnding, Sub(s, e1)
                                     If IsCommiting Then Return
                                     IsCommiting = True
                                     g.CommitEdit(DataGridEditingUnit.Row, True)
                                     IsCommiting = False
                                 End Sub
End Sub

Public Shared Function GetForceEndEdit(o As DependencyObject) As Boolean
    Return o.GetValue(ForceEndEditProp)
End Function

Public Shared Sub SetForceEndEdit(ByVal o As DependencyObject, ByVal value As Boolean)
    o.SetValue(ForceEndEditProp, value)
End Sub

This basicly force the grid to set IsEditing = false on the datagridrow, when any cell stops editing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文