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

Wpf 用于检查DataGrid的单元格当前是否已编辑的代码,wpf,wpfdatagrid,Wpf,Wpfdatagrid,是否可以简单地检查DataGrid当前是否处于编辑模式(不需要订阅BeginingEdit和CellEditEnding)好的,我还没有找到一个简单的解决方案,也没有人给我指出。以下代码可用于向DataGrid添加附加属性IsInEditMode。希望它能帮助某人: public class DataGridIsInEditModeTracker { public static bool GetIsInEditMode(DataGrid dataGrid) { retu

是否可以简单地检查DataGrid当前是否处于编辑模式(不需要订阅BeginingEdit和CellEditEnding)

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

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);
    }                  
}
公共类DataGridIsInEditModeTracker{
公共静态bool GetIsInEditMode(DataGrid DataGrid){
return(bool)dataGrid.GetValue(IsInEditModeProperty);
}
私有静态void SetIsInEditMode(DataGrid DataGrid,布尔值){
SetValue(IsInEditModePropertyKey,value);
}
私有静态只读DependencyPropertyKey IsInEditModePropertyKey=DependencyProperty.RegisterAttachedReadOnly(“IsInEditMode”、typeof(bool)、typeof(DataGridIsInEditModeTracker)、new UIPropertyMetadata(false));
公共静态只读DependencyProperty IsInEditModeProperty=IsInEditModePropertyKey.DependencyProperty;
公共静态bool GetProcessIsInEditMode(DataGrid DataGrid){
return(bool)dataGrid.GetValue(ProcessIsInEditModeProperty);
}
公共静态void setProcessineditMode(DataGrid DataGrid,bool值){
SetValue(ProcessIsInEditModeProperty,值);
}
公共静态只读从属属性ProcessinedItModeProperty=
DependencyProperty.RegisterAttached(“ProcessIsInEditMode”、typeof(bool)、typeof(DataGridIsInEditModeTracker)、new FrameworkPropertyMetadata(false、delegate(DependencyObject d、DependencyPropertyChangedEventArgs e){
DataGrid DataGrid=d作为DataGrid;
if(null==dataGrid){
抛出新的InvalidOperationException(“ProcessIsInEditMode只能用于DataGrid类的实例”);
}
if((bool)e.NewValue){
dataGrid.BeginningEdit+=新事件处理程序(dataGrid\u BeginningEdit);
dataGrid.CellEditEnding+=新的事件处理程序(dataGrid\u CellEditEnding);
}否则{
dataGrid.BeginningEdit-=新事件处理程序(dataGrid_BeginningEdit);
dataGrid.CellEditEnding-=新事件处理程序(dataGrid\u CellEditEnding);
}
}));
静态无效dataGrid_CellEditEnding(对象发送方,DataGridCellEditEndingEventArgs e){
SetIsInEditMode((DataGrid)发送方,false);
}
静态void dataGrid_BeginningEdit(对象发送方,DataGridBeginningEditEventArgs e){
SetIsInEditMode((DataGrid)发送方,true);
}                  
}
要使用它,请在datagrid上将ProcessIsInEditMode-属性设置为true:

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

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

我找到了一个较短的解决方法(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

公共函数GetContainerFromIndex(作为DependencyObject的TContainer的)_
(ByVal Items控件作为Items控件,ByVal索引作为整数)作为TContainer
返回直接广播(
itemsControl.ItemContainerGenerator.ContainerFromIndex(索引),TContainer)
端函数
公共函数IsEditing(ByVal dataGrid作为dataGrid)为布尔值
Return dataGrid.GetEditingRow不是空的
端函数
公共函数GetEditingRow(ByVal dataGrid作为dataGrid)作为DataGridRow
Dim sIndex=dataGrid.SelectedIndex
如果sIndex>=0,则
选定的Dim=dataGrid.GetContainerFromIndex(DataGridRow的)(sIndex)
如果选择。i编辑,则返回所选
如果结束
对于i=0到dataGrid.Items.Count-1
如果i=sIndex,则继续
Dim item=dataGrid.GetContainerFromIndex(属于DataGridRow)(i)
如果item.i正在编辑,则返回项
下一个
一无所获
端函数
C#:

公共静态TContainer GetContainerFromIndex
(此项控件项控件,int索引)
其中TContainer:DependencyObject
{
返回(t容器)
itemsControl.ItemContainerGenerator.ContainerFromIndex(索引);
}
公共静态布尔IsEditing(此DataGrid DataGrid)
{
返回dataGrid.GetEditingRow()!=null;
}
公共静态DataGridRow GetEditingRow(此DataGrid DataGrid)
{
var sIndex=dataGrid.SelectedIndex;
如果(sIndex>=0)
{
所选变量=dataGrid.GetContainerFromIndex(sIndex);
如果选择(已选,编辑)返回选择;
}
对于(int i=0;i
您似乎也可以从“项目”视图中获取此信息,即:

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

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

以上使用datagridrow上的IsEdit或IEditableCollectionView上的IsEdit的所有答案都是我的部分答案:

如果用户输入edition,然后在任何其他单元格上单击clics,则会触发EndEdit事件,但DataGridRow仍具有属性IsEditing to 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。

太好了,谢谢,根据我的意见,您应该将其发布到Microsoft的连接中,并在此处发布一个链接,以便用户可以投票支持在即将发布的版本中立即实现。我建议将DependencyProperty obj参数替换为DataGrid dg,因此,附加属性只能应用于DataGrid类型的对象。如何确保在XAML等中声明其他处理程序之前到达此行为的处理程序?我找到了它,很简单,我使用的是PreparingCellForEdit事件,它在开始后引发
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