est-il d'une simple possibilité de vérifier si le DataGrid est actuellement en mode édition (Sans souscrire à BeginningEdit et CellEditEnding)code pour vérifier si une cellule d'un DataGrid est en cours d'édition
Répondre
Ok, je ne ai pas trouvé une solution simple et personne ne m'a pointé à un. Le code suivant peut être utilisé pour ajouter une propriété attachée IsInEditMode à un DataGrid. Il aide quelqu'un l'espoir:
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);
}
}
Pour l'utiliser, mettre sur la grille de données de la propriété ProcessIsInEditMode- true:
<DataGrid local:DataGridIsInEditModeTracker.ProcessIsInEditMode="True" .. other properties ..>
Afer que vous aurez la IsInEditMode-propriété en phase avec le mode de Grille de données. Si vous souhaitez également la cellule d'édition, modifiez le code en BeginningEdit
de manière concise.
Je trouve une solution plus courte (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;
}
Parfois, GetContainerFromIndex ne renvoie pas de valeur. Je ne suis pas sûr si cela a quelque chose à voir avec des objets virtuels/non créés. Par conséquent item.IsEditing dans GetEditingRow provoque une exception NullReferenceException. Mais peu importe; c'est quelque chose de mineur et vous avez résolu mon problème: +1 – Markus
@Markus devriez-vous jamais trouver un sln à ce que s'il vous plaît buzz dans – Shimmy
Il vous semble peut également obtenir cette information de la vue des articles, à savoir cela fonctionne:
IEditableCollectionView itemsView = stateGrid.Items;
if (itemsView.IsAddingNew || itemsView.IsEditingItem)
{
stateGrid.CommitEdit(DataGridEditingUnit.Row, true);
}
Je ne l'ai pas confirmé, mais il est très probable que vous puissiez obtenir ces drapeaux dans un viewmodel si votre collection liée fournit un IEditableCollectionView.
Toutes les réponses ci-dessus en utilisant IsEditing sur le datagridrow ou IsEdititngItem sur la IEditableCollectionView sont des réponses partielles à moi:
Si l'utilisateur d'entrer édition, puis clics sur une autre cellule, l'événement EndEdit est tiré mais le DataGridRow a Toujours la propriété IsEditing à True !!! Et si vous essayez de trouver le responsable DataGridCell, son IsEditingProperty est toujours faux ... Je pense que c'est un bug. Et d'avoir le comportement souhaité, je devais écrire cette solution truand
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
Cette force basiquement la grille pour définir IsEditing = false sur le datagridrow, quand toute modification arrête cellule.
Très bien, merci, à mon avis, vous devriez le publier dans une connexion à Microsoft et poster ici un lien afin que l'utilisateur puisse voter pour qu'il soit mis en œuvre dans la prochaine version. – Shimmy
Je suggère de remplacer les paramètres obj DependendencyProperty avec DataGrid dg, de sorte que la propriété jointe peut être appliquée uniquement aux objets de type DataGrid. – Shimmy
Vous avez raison - je l'ai changé. – HCL