2011-12-07 45 views
5

Tôi cần phải có loại sự kiện Sorted cho số DataGrid trong một ứng dụng WPF nhưng không thể tìm được cách để lấy nó.Làm thế nào tôi có thể được thông báo nếu cột DataGrid được sắp xếp (và không sắp xếp)

Đây là những gì tôi đã cố gắng:

Các DataGrid cung cấp một sự kiện Sorting, nhưng tôi không thể sử dụng nó như nó được bắn trước khi phân loại được thực hiện. Các EventArgs cho tôi cột được sắp xếp nhưng không phải là cách nó được sắp xếp và nếu tôi nhận được hướng sắp xếp nó được đặt thành giá trị cũ. Tất nhiên tôi có thể đoán nó sẽ như thế nào khi tôi biết rằng nó lật từ không để tăng dần và cuối cùng là giảm dần nhưng điều đó sẽ không có giải pháp vì nó sẽ thất bại nếu hành vi của điều khiển thay đổi.

Second try:

Các DataGrid có một cái nhìn mặc định cung cấp truy cập đến một SortDescriptionCollection. Bộ sưu tập này chứa tất cả các thuộc tính sắp xếp nhưng tôi không thấy bất kỳ khả năng nào để cho phép tôi thông báo về các thay đổi.

Tôi phải nói rằng tôi đang tìm một giải pháp càng sạch càng tốt vì nó sẽ được sử dụng trong một dự án lớn mà tôi không thể sử dụng các giải pháp có thể thất bại nếu môi trường thay đổi.

Có ai biết từ kinh nghiệm (hoặc tài liệu?) Cách tôi có thể giải quyết vấn đề này?

Chỉnh sửa: Để làm rõ hơn những gì tôi muốn đạt được: Tôi cần được thông báo rằng cột DataGrid được sắp xếp theo hướng nào khi người dùng sắp xếp cột. Không cần thiết thông tin này xuất hiện sau khi tự sắp xếp, nó chỉ cần chính xác;)

Trả lời

14

tôi thực hiện các Sắp xếp cho sự kiện DataGrid bản thân mình bằng cách ghi đè DataGrid như sau:

public class ValueEventArgs<T> : EventArgs 
{ 
    public ValueEventArgs(T value) 
    { 
     Value = value; 
    } 

    public T Value { get; set; } 

} 

public class DataGridExt : DataGrid 
{ 
    public event EventHandler<ValueEventArgs<DataGridColumn>> Sorted; 

    protected override void OnSorting(DataGridSortingEventArgs eventArgs) 
    { 
     base.OnSorting(eventArgs); 

     if (Sorted == null) return; 
     var column = eventArgs.Column; 
     Sorted(this, new ValueEventArgs<DataGridColumn>(column)); 
    } 
} 

Để sử dụng nó thì tất cả các bạn cần làm là:

private void Initialize() 
    { 
      myGrid.Sorted += OnSorted; 
    } 
    private void OnSorted(object sender, ValueEventArgs<DataGridColumn> valueEventArgs) 
    { 
    // Persist Sort... 
    } 
0

Sau nhiều giờ thử và đọc, tôi đã tự mình giải quyết được vấn đề. Tôi không hoàn toàn hài lòng với giải pháp nhưng nó hoạt động cho tôi.

Khi tôi cho phép tạo các cột DataGrid theo mã, tôi có thể sử dụng DependencyPropertySortDirection của mỗi cột và thêm phương thức sẽ được gọi khi thuộc tính thay đổi. Điều này được thực hiện theo cách này:

DataGridBoundColumn column = GetTheColumnIWantToObserve(); 
if (column != null) 
{ 
    // add value changed notification to be informed about changes 
    var desc = DependencyPropertyDescriptor.FromProperty(DataGridColumn.SortDirectionProperty, typeof(DataGridColumn)); 
    desc.AddValueChanged(column, ColumnSortDirectionChanged); 
} 

Trong phương pháp ColumnSortDirectionChanged Bây giờ tôi có thể làm việc với các thay đổi.

private void ColumnSortDirectionChanged(object sender, EventArgs eventArgs) 
{ 
    var column = sender as DataGridColumn; 
    if (column != null) 
    { 
     var newSortDirection = column.SortDirection; 
     // Yay, I got it!! 
    } 
} 

Nếu tôi sẽ không tạo ra các cột bản thân mình tôi sẽ phải sử dụng một sự kiện DataGrid (ví dụ Loaded hoặc AutoGeneratedColumns) và thêm các thông báo cho tất cả các cột hiện có.

+0

Đó thực sự là giải pháp như vậy. SortDirection thay đổi thời điểm bạn nhấp vào Sắp xếp. Việc phân loại thực tế có thể mất nhiều thời gian hơn, bạn không đảm bảo rằng giải pháp của bạn sẽ khởi động chính xác sau khi sắp xếp xong. – Houman

+0

Vì vậy, bạn đã có một ý tưởng khác? Đối với tôi điều này là tốt khi tôi sử dụng thông tin để lưu trữ nó trong một tập tin cấu hình để bắt đầu ứng dụng tiếp theo. Thời gian không quan trọng lắm. Tuy nhiên, như tôi đã viết, tôi không hoàn toàn hài lòng với điều này, vì vậy tôi muốn được hạnh phúc về đề xuất. – MatthiasG

1

tôi có thể không nhận được giải pháp của Stephen Lautier để làm việc trong VB.Net, nhưng tôi đã tìm thấy một giải pháp khác có thể hoạt động.

Bất cứ khi nào một hoạt động phân loại xảy ra, các sự kiện sau đây xảy ra theo thứ tự niêm yết:

  1. Sorting
  2. UnloadingRow (Đối với tất cả các hàng trong DataGrid)
  3. LoadingRow (Đối với tất cả các hàng trong DataGrid)
  4. LayoutUpdated

này có thể được sử dụng trong các cách sau:

Biến

Private _updateSorted As Boolean 
Private _tempSender As Object 
Private _rowsLoaded As List(Of DataGridRowEventArgs) 
_rowsLoaded = New List(Of DataGridRowEventArgs) 

Sorting

Private Sub myDataGrid_Sorting(sender As Object, e As DataGridSortingEventArgs) Handles myDataGrid.Sorting 
    _updateSorted = True 
    _rowsLoaded.Clear() 
    _tempSender = Nothing 
End Sub 

UnloadingRow/tải Row Sự kiện

'Save pre-sorting state here, if desired' 
'Perform operation on pre-sorting rows here, if desired' 
Private Sub myDataGrid_UnloadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.UnloadingRow 

End Sub 

'Save post-sorting state here.' 
'Perform operation on post-sorting rows here' 
'In this example, the operation is dependent on the DataGrid updating its layout first so I included items relevant to handling that' 
Private Sub myDataGrid_LoadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.LoadingRow 
    Dim myDataGridCell As DataGridCell = GetCellByRowColumnIndex(myDataGrid, e.Row.GetIndex, colIndex) 
    'Or whatever layout-dependent object you are using, perhaps utilizing e As DataGridRowEventArgs' 

     If Not IsNothing(myDataGridCell) Then 
      '~~ Perform operations here ~~' 
     Else 
      If _updateSorted Then 
       'Update has occurred but the updated DataGrid is not yet available' 
       'Save variables to use once the DataGrid is updated' 
       _rowsLoaded.Add(e) 
       _tempSender = sender 
      End If 
     End If 
End Sub 

La youtUpdated

Private Sub myDataGrid_LayoutUpdated(sender As Object, e As EventArgs) Handles myDataGrid.LayoutUpdated 
    If _updateSorted Then 
     Dim rowsLoaded As New List(Of DataGridRowEventArgs) 
     For Each eRow As DataGridRowEventArgs In _rowsLoaded 
      rowsLoaded.Add(eRow) 
     Next 

     For Each eRow As DataGridRowEventArgs In rowsLoaded 
      'Now perform the action to the sorted DataGridRows in the order they were added' 
      myDataGrid_LoadingRow(_tempSender, eRow) 
     Next 
     _updateSorted = False 
    End If 
End Sub 
+0

Bạn đã tìm thấy thông tin về thứ tự sự kiện ở đâu? Tôi đang cố gắng sử dụng sự kiện LayoutUpdated (khi trước bởi một sự kiện sắp xếp) làm trình kích hoạt của tôi để cuộn dữ liệu lên trên cùng. Trong khi tất cả các cuộc gọi liên quan xuất hiện để được thực hiện như dự định, hành vi cuối cùng không xảy ra - DataGrid của tôi không di chuyển đến đầu sau một loại. Thay vào đó, nó giữ hàng được chọn trong chế độ xem. –

+0

Tôi ước gì tôi biết một nguồn tham khảo, nhưng tôi thì không! Thay vào đó tôi đã làm một số thử nghiệm. Về cơ bản, trong những tình huống này, tôi cố gắng tạo ra các sự kiện khác nhau hoặc là những gì tôi nghĩ rằng tôi muốn hoặc có liên quan. Sau đó tôi có trình xử lý sự kiện gửi một thông báo mang tính thông tin đến bàn điều khiển. Bằng cách đó, báo cáo không can thiệp vào việc sử dụng GUI và các thông báo cho tôi biết rằng một sự kiện cụ thể đã được kích hoạt. Qua thử và sai, tôi có thể nhận được hình ảnh về thứ tự kích hoạt, tần suất, mẫu hoặc mức độ phù hợp của nó với các thiết lập và hành động khác nhau. – PellucidWombat

+0

Tình huống của bạn có vẻ như tùy thuộc vào các tùy chọn nhất định mà bạn đã đặt trong mã dữ liệu hoặc mã liên quan, chẳng hạn như cuộn tự động để chọn. Vì vậy, nếu đó không phải là những gì bạn muốn, tôi sẽ xem xét cách lựa chọn của bạn được duy trì hoặc thiết lập lại sau khi bắt đầu một loại. Điều này có thể cung cấp cho bạn một đầu mối về vị trí/cách thay đổi hành vi. – PellucidWombat

Các vấn đề liên quan