Có một khả năng đơn giản để kiểm tra xem DataGrid hiện đang trong EditMode (Nếu không đăng ký BeginningEdit và CellEditEnding)Mã để kiểm tra xem một tế bào của một DataGrid hiện đang sửa
Trả lời
Ok, tôi havent tìm thấy một giải pháp đơn giản và không ai chỉ cho tôi một. Đoạn mã sau có thể được sử dụng để thêm một thuộc tính đính kèm IsInEditMode vào một DataGrid. Hy vọng nó sẽ giúp ai đó:
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);
}
}
Để sử dụng nó, đặt trên DataGrid tài sản ProcessIsInEditMode- true:
<DataGrid local:DataGridIsInEditModeTracker.ProcessIsInEditMode="True" .. other properties ..>
Afer rằng bạn sẽ có IsInEditMode-bất động sản đồng bộ với chế độ của Lưới dữ liệu. Nếu bạn cũng muốn ô chỉnh sửa, hãy thay đổi mã trong BeginningEdit
accoringly.
Tôi tìm thấy một workaround ngắn hơn (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;
}
Đôi khi GetContainerFromIndex không trả lại giá trị. Tôi không chắc chắn nếu nó có cái gì để làm với các mục ảo/không được tạo ra. Vì vậy item.IsEditing trong GetEditingRow gây ra một NullReferenceException. Nhưng dù sao; đây là điều nhỏ nhặt và bạn đã giải quyết được sự cố của mình: +1 – Markus
@Markus nếu bạn đã từng tìm thấy một dấu vết cho điều đó, vui lòng buzz – Shimmy
Có vẻ như bạn cũng có thể nhận được thông tin này từ mục xem, cụ thể là công trình này:
IEditableCollectionView itemsView = stateGrid.Items;
if (itemsView.IsAddingNew || itemsView.IsEditingItem)
{
stateGrid.CommitEdit(DataGridEditingUnit.Row, true);
}
Tôi đã không xác nhận điều này nhưng rất có thể bạn có thể nhận được những lá cờ này trong một viewmodel nếu bộ sưu tập bị ràng buộc của bạn cung cấp một IEditableCollectionView.
Tất cả các câu trả lời ở trên sử dụng IsEditing trên datagridrow hoặc IsEdititngItem trên IEditableCollectionView là câu trả lời một phần với tôi:
Nếu người dùng nhập phiên bản, sau đó clics trên bất kỳ tế bào khác, sự kiện EndEdit là bắn nhưng DataGridRow có vẫn là tài sản IsEditing to True !!! Và nếu bạn cố gắng tìm DataGridCell chịu trách nhiệm, IsEditingProperty của nó luôn luôn là sai ... Tôi nghĩ rằng đó là một lỗi. Và để có hành vi mong muốn, tôi đã phải viết workaround Ugly này
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
này về cơ bản buộc các lưới để đặt IsEditing = false trên datagridrow, khi bất kỳ tế bào dừng lại chỉnh sửa.
- 1. thực hiện chỉnh sửa tế bào jqgrid datepicker
- 2. Nhiều dòng trong một tế bào của một bảng
- 3. Bắt trị tế bào nào trong DataGrid trong WPF
- 4. Làm thế nào bạn có thể chỉnh sửa một tế bào QTableView từ một thử nghiệm đơn vị QTest?
- 5. Làm thế nào để kiểm tra xem một NSProgressIndicator hiện đang hoạt hình?
- 6. Excel: Set màu nền của tế bào để giá trị rgb dữ liệu trong tế bào
- 7. UITableView Phát hiện tế bào cuối
- 8. iOS: tế bào cellForRowAtIndexPath đang nhận được lẫn lộn
- 9. Làm thế nào để có được ComboBox cấp tế bào cho WPF DataGrid?
- 10. Kiểm tra xem mã đang chạy trên GPU hay CPU
- 11. Kiểm tra xem mảng di động là một tập hợp con của một Nother trong Matlab
- 12. Preallocation của mảng tế bào trong MATLAB
- 13. Làm thế nào để đếm các nhóm của cùng một tế bào trong một mảng 2d?
- 14. Cách kiểm tra xem một tệp hiện có đang được ghi vào
- 15. Làm thế nào để bọc đường trong một tế bào jtable?
- 16. Orgmode Bảng Formatting của tế bào
- 17. Làm cách nào để kiểm tra xem ngày hiện tại có đang hoạt động vào ngày
- 18. Kiểm tra xem một thể hiện của một đối tượng là chỉ đọc
- 19. PHP: Kiểm tra xem biến có phải là một thể hiện của một lớp nhất định
- 20. Xóa các phần tử từ một tế bào trong Matlab
- 21. Return giá trị '1' một tế bào tham chiếu rỗng
- 22. DataGridView với vấn đề tế bào CheckBox
- 23. Ruby - Kiểm tra xem cổng có đang mở
- 24. mã ngắn nhất để kiểm tra xem một số là trong một phạm vi trong JavaScript
- 25. Kiểm tra xem tệp có đang mở
- 26. tế bào Storyboard tĩnh: dequeueReusableCellWithIdentifier trả về nil
- 27. Kiểm tra xem Chronometer có đang chạy
- 28. Có sử dụng GetProcessesByName hay nhất để kiểm tra xem một tiến trình đang chạy không?
- 29. Làm thế nào để kiểm tra xem một tiến trình đang chạy bằng Delphi?
- 30. Gán một màu nền cho một ô, đưa ra một điều kiện trên tế bào khác
Tuyệt vời, cảm ơn, cho ý kiến của tôi bạn nên đăng bài này trong một kết nối với Microsoft và đăng ở đây một liên kết để người dùng có thể bỏ phiếu cho nó được thực hiện out-the-box trong phiên bản sắp tới. – Shimmy
Tôi sẽ đề nghị thay thế các tham số obendendencyProperty obj bằng DataGrid dg, vì vậy thuộc tính đính kèm chỉ có thể được áp dụng cho các đối tượng kiểu DataGrid. – Shimmy
Bạn nói đúng - tôi đã thay đổi nó. – HCL