2016-04-10 14 views
0

GridViews Seçilen hücreler bir IList, bu yüzden ViewModel'imden seçim eklediğimde görünümü güncelleştirmiyor.GridvView.SelectedCells.Add() görünüm güncelleştirmiyor

Seçilen Hücreler için görünümü güncelleştirmeyi zorlamanın bir yolu var mı? Şu anda görünümleri düzenleme şeklim, ViewModel'deki listeyi güncelleştiren bir Eklenmiş davranışa sahip olmakla kalmıyor, aynı zamanda GridView, ancak GridView görsellerini güncelleştirmiyor.

public static List<GridCell> GetSelectedCells(DependencyObject obj) 
    { 
     return (List<GridCell>)obj.GetValue(SelectedCellsProperty); 
    } 
    public static void SetSelectedCells(DependencyObject obj, List<GridCell> value) 
    { 
     obj.SetValue(SelectedCellsProperty, value); 
    } 
    public static readonly DependencyProperty SelectedCellsProperty = 
     DependencyProperty.RegisterAttached("SelectedCells", typeof(List<GridCell>), typeof(DataGridHelper), new UIPropertyMetadata(null, OnSelectedCellsChanged)); 
    static SelectedCellsChangedEventHandler GetSelectionChangedHandler(DependencyObject obj) 
    { 
     return (SelectedCellsChangedEventHandler)obj.GetValue(SelectionChangedHandlerProperty); 
    } 
    static void SetSelectionChangedHandler(DependencyObject obj, SelectedCellsChangedEventHandler value) 
    { 
     obj.SetValue(SelectionChangedHandlerProperty, value); 
    } 
    static readonly DependencyProperty SelectionChangedHandlerProperty = 
     DependencyProperty.RegisterAttached(nameof(SelectedCellsChangedEventHandler), typeof(SelectedCellsChangedEventHandler), typeof(DataGridHelper), new UIPropertyMetadata(null)); 

    private static bool NewResouce = false; 
    static void OnSelectedCellsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) 
    { 
     if (d is DataGrid) 
     { 
      NewResouce = true; 
      DataGrid datagrid = d as DataGrid; 
      if (GetSelectionChangedHandler(d) == null) 
      { 
       SelectedCellsChangedEventHandler selectionchanged = (sender, e) => 
       { 
        if (!NewResouce) 
        { 

         List<GridCell> cells = new List<GridCell>(); 
         foreach (var selectedell in datagrid.SelectedCells) 
         { 
          string header = selectedell.Column.Header.ToString(); 
          GridCell cell = new GridCell 
          { 
           RowIndex = datagrid.Items.IndexOf(selectedell.Item), 
           ColumnIndex = selectedell.Column.DisplayIndex, 
           Parent = selectedell.Item as ExpandoObject, 
           ColumnHeader = header, 
           Value = (selectedell.Item as IDictionary<string, object>)[header] 
          }; 
          cells.Add(cell); 
         } 
         SetSelectedCells(d, cells); 
        } 
       }; 
       SetSelectionChangedHandler(d, selectionchanged); 
       datagrid.SelectedCellsChanged += GetSelectionChangedHandler(d); 
      } 

      foreach (var selected in GetSelectedCells(d) as List<GridCell>) 
      { 

       DataGridCellInfo cell = new DataGridCellInfo(selected.Parent, datagrid.Columns[selected.ColumnIndex]); 
       if (!datagrid.SelectedCells.Contains(cell)) 
       { 
        datagrid.SelectedCells.Add(cell); 
       } 

      } 

      NewResouce = false; 
     } 

    } 
} 

i NewResource boolean sahip sebebi, olay seçimi ben yeni seçilen öğe eklerken aslında ateş etmez değişti olmasıdır:

burada ekli davranıştır. Sadece seçimlerini güncellemeyen görünümü.

SelectedCells, bir sekmenin içinde bulunduğu için, görünüm yüklendikten sonra eklenir ve görünüm yüklenmeden önce grileşme görünümündeki veriler boş gibi görünür, bu nedenle görünüm yüklenmeden önce seçilemiyorum.

+0

Sonunda ne yapmaya çalışıyorsun? – AnjumSKhan

+0

Sadece seçili bir hücre listesini bağlayarak viewmodel'den bir şeyler seçiyorum, ancak bunu çözdüm, DataGridCell'i almalı ve sadece onları IsSelected olarak ayarlamalı ve onu düzeltir. –

cevap

0

Soru basit. Lütfen liste yerine bir ObservableCollection kullanın. Gözlemlenebilir koleksiyon bağımlılık nesnesidir ve özellik değişikliği ile ilgili bildirimde bulunmak üzere görünüme bir propertyChanged olayı yükseltir ve görünüm güncellenir. bu i datagrid'e bazı uzantısı yöntemi eklendi çalışması için

static void OnSelectedCellsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) 
    { 
     if (d is DataGrid) 
     { 

      DataGrid datagrid = d as DataGrid; 
      if (GetSelectionChangedHandler(d) == null) 
      { 
       SelectedCellsChangedEventHandler selectionchanged = (sender, e) => 
       { 


         List<GridCell> cells = new List<GridCell>(); 
         foreach (var selectedell in datagrid.SelectedCells) 
         { 
          string header = selectedell.Column.Header.ToString(); 
          GridCell cell = new GridCell 
          { 
           RowIndex = datagrid.Items.IndexOf(selectedell.Item), 
           ColumnIndex = selectedell.Column.DisplayIndex, 
           Parent = selectedell.Item as ExpandoObject, 
           ColumnHeader = header, 
           Value = (selectedell.Item as IDictionary<string, object>)[header] 
          }; 
          cells.Add(cell); 

         } 
         SetSelectedCells(d, cells); 


       }; 
       SetSelectionChangedHandler(d, selectionchanged); 
       datagrid.SelectedCellsChanged += GetSelectionChangedHandler(d); 
      } 

      foreach (var selected in GetSelectedCells(d) as List<GridCell>) 
      { 

        DataGridCell actualCell = datagrid.GetCell(selected.RowIndex, selected.ColumnIndex); 
        actualCell.IsSelected = true; 
        actualCell.Focus(); 
       } 

      } 

     } 

, daha kolay burada Cell almak için yapmak: Ben DataGridCells üzerine, INotifyPropertyChanged uyguluyor mu bazı özellikleri finden heres çözümü sona erdi

+0

GridView'ı zaten WPF'de oluşturmamıştım, bu yüzden ne kullanacağımı seçemiyorum. –

+0

Yine de listenin yerine ObservableCollection'ı kullanabiliyorsanız, bunun çalışması gerekir. – ViVi

0

İlavesi: (çalınan bu blog)

public static T GetVisualChild<T>(Visual parent) where T : Visual 
    { 
     T child = default(T); 
     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 
    public static DataGridCell GetCell(this DataGrid grid, int rowIndex, int columnIndex) 
    { 
     return GetCell(grid, GetRow(grid, rowIndex), columnIndex); 
    } 
    public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column) 
    { 
     if (row != null) 
     { 
      DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row); 

      if (presenter == null) 
      { 
       grid.ScrollIntoView(row, grid.Columns[column]); 
       presenter = GetVisualChild<DataGridCellsPresenter>(row); 
      } 

      DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); 
      return cell; 
     } 
     return null; 
    } 
    public static DataGridRow GetRow(this DataGrid grid, int index) 
    { 
     DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index); 
     if (row == null) 
     { 
      // May be virtualized, bring into view and try again. 
      grid.UpdateLayout(); 
      grid.ScrollIntoView(grid.Items[index]); 
      row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index); 
     } 
     return row; 
    }