2013-03-12 15 views
7

Zasadniczo powiązałem datagrid tak, aby przypominał harmonogram przedmiotów - każdy wiersz reprezentuje semestr przedmiotów, a każda komórka w tym semestrze reprezentuje temat.Jak mogę uzyskać dostęp do obiektu danych obiektu DataGridCell w kodzie?

Próbuję teraz dodać funkcję przeciągania i upuszczania, aby przeciągnąć dodatkowe obiekty na siatkę, co spowoduje aktualizację bazowej struktury danych.

Mogę użyć niektórych metod wizualnego drzewa do znalezienia obiektu DataGridCell, do którego użytkownik przeciąga nowy obiekt, ale nie wiem, jak uzyskać dostęp do wartości (podmiotu), do której jest ona powiązana, aby zamień pustą/zastępczą wartość na nowy temat. Czy istnieje sposób dostępu do wartości bazowej lub czy powinienem zrestrukturyzować całą moją metodę tworzenia tego programu?

An example of the grid and the subjects to be dragged onto it

+0

czy możesz wkleić strukturę siatki? – Freelancer

+0

Fizyczny widok GridView lub jego struktura? – Miguel

+0

tylko kolumny i dane z zera – Freelancer

Odpowiedz

3

Aby uzyskać dane o DataGridCell, można użyć to DataContext i właściwość Column. Sposób, w jaki to zrobić, zależy dokładnie od tego, jakie są dane wiersza, tj. Jakie elementy umieszczasz w kolekcji DataGrid ItemsSource. Zakładając, że przedmioty są object[] tablice:

// Assuming this is an array of objects, object[],this gets you the 
// row data as you have them in the DataGrid's ItemsSource collection 
var rowData = (object[]) DataGrid.SelectedCells[0].Item; 
// This gets you the single cell object 
var celldata = rowData[DataGrid.SelectedCells[0].Column.DisplayIndex]; 

Jeśli dane wiersz jest bardziej złożona, trzeba napisać według metody, która przekłada właściwość Column i element danych rząd do określonej wartości na pozycji danych rzędu.


EDIT:

Jeśli komórka upuścić dane do nie jest wybrana komórka, jedną z opcji jest uzyskanie DataGridRow do którego DataGridCell należy, używając VisualTreeHelper:

var parent = VisualTreeHelper.GetParent(gridCell); 
while(parent != null && parent.GetType() != typeof(DataGridRow)) 
{ 
    parent = VisualTreeHelper.GetParent(parent); 
} 
var dataRow = parent; 

Następnie masz rząd i możesz postępować jak powyżej.


Ponadto chodzi o Twoje pytanie, czy należy ponownie rozważyć sposób, proponuję przy użyciu niestandardowych WPF zachowanie ruchowe s.

Zachowania zapewniają bardzo prosty sposób rozszerzania możliwości sterowania za pomocą kodu C#, a nie XAML, zachowując przy tym prostotę i prostotę kodu (co jest nie tylko przyjemne, jeśli podążacie za MVVM). Zachowania są zaprojektowane w taki sposób, aby można je było ponownie wykorzystać i nie były związane z konkretną kontrolą.

Here's a good introduction

Dla szczególnego przypadku, mogę tylko dać wyobrażenie o tym, co należy zrobić:

napisać DropBehavior dla kontroli TextBlock (lub cokolwiek kontrolować chcesz wewnątrz firmy DataGridCells, który obsługuje spadek. podstawowym założeniem jest, aby zarejestrować według działań do EVNT komórek w sposobie kontrolą OnAttached().

public class DropBehavior : Behavior<TextBlock> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.MouseUp += AssociatedObject_MouseUp; 
    } 

    private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     // Handle what happens on mouse up 

     // Check requirements, has data been dragged, etc. 
     // Get underlying data, now simply as the DataContext of the AssociatedObject 
     var cellData = AssociatedObject.DataContext; 

    } 
} 

zauważyć, że podczas analizowania danych z pojedynczej komórki fro m dane wiersza i właściwość Column stają się nieaktualne.

Następnie należy podłączyć ten problem do TextBlocks, które można umieścić wewnątrz komórek, stosując ContentTemplate z CellStyle swojej DataGrid:

<DataGrid> 
    <DataGrid.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <TextBlock Text="{Binding}"> 
          <i:Interaction.Behaviors> 
           <yourns:DropBehavior/> 
          </i:Interaction.Behaviors> 
         </TextBlock> 
        </DataTemplate> 
       </Setter.Value> 

      </Setter> 
     </Style> 
    </DataGrid.CellStyle> 
</DataGrid> 

można znaleźć Behavior<T> klasy bazowej w

Systemu .Windows.Interactivity.dll

Nie testowałem tego, ale mam nadzieję, że działa dla ciebie i masz pomysł ...

+0

Zajrzę do rzeczy o zachowaniu WPF, dzięki za link. Jednak w pierwszej części odpowiedzi nie mogę wykonać żadnego z twoich rozwiązań. W pierwszym przykładzie używasz DataGrid.SelectedCells [0], który zwraca DataGridCellInfo, którego * nie mam *. Pamiętaj, że mam tylko DataGridCell, który dostałem z pozycji myszy po przeciągnięciu, nie mam wyboru. Mogę wybrać tę komórkę, a następnie zrobić tę metodę, ale wolałbym nie zmieniać wyboru użytkownika. – Miguel

+0

W drugiej metodzie używasz rowData [Column Index]. Mogę uzyskać indeks kolumny, ponieważ mam kolumnę (jest to właściwość DataGridCell), ale nie znam bieżącego wiersza komórki, aby uzyskać właściwą strukturę rowsData. – Miguel

+0

@Miguel: Dited mój post. Zdecydowanie polecam używanie zachowań. To naprawdę nie jest tak skomplikowane i imho to wszystko szuka w wierszu rodziców, a rzucanie dookoła nie jest ani dobrym stylem, ani wydajnym. – Marc

Powiązane problemy