2011-04-27 16 views
9

I opracowali WPF UserControl, który ma być używany jako lista pick następująco:Jak powiązać Command dwukrotne kliknięcie na wiersz w DataGrid

  • DataGrid związany z CollectionView podmiotów (np. Pracowników)
  • Pole tekstowe powyżej elementu DataGrid, które może być używane do filtrowania elementów wyświetlanych w DataGrid.

Chcę odsłonić polecenie, które zostanie wykonane po dwukrotnym kliknięciu przez użytkownika wiersza w obiekcie DataGrid. Pojemnik może wtedy zareagować na to, wykonując coś z SelectedItem w DataGrid.

Do tej pory starałem się obsłużyć dwukrotnie kliknąć w następujący sposób:

<DataGrid IsReadOnly="True"> 
    <DataGrid.InputBindings> 
     <MouseBinding MouseAction="LeftDoubleClick" Command="... /> 
    </DataGrid.InputBindings> 
... 

Jednak dwukrotnie kliknąć zdarzenie nadal odpala, gdy użytkownik kliknie w nagłówku DataGrid. Chciałbym móc go ograniczyć, aby polecenie było wykonywane tylko wtedy, gdy podwójne kliknięcie znajduje się w ciele składnika DataGrid. Czy istnieje deklaratywny sposób na zrobienie tego?

UPDATE

Ja tylko zaznajomienie się z WPF i MVVM, i jestem naprawdę szuka wskazówek dotyczących sposobu realizacji niskopoziomowych komponentów wielokrotnego użytku, takich jak ten. Wszelkie ogólne porady również zostaną z wdzięcznością przyjęte i wznowione. W obecnej formie, jestem przy założeniu będę chciał ten UserControl do:

  • narazić właściwość zależność „SelectedItem”, który jest związany z DataGrid za selectedItem

  • narazić RoutedEvent „itemDoubleClick” lub podobne, że jest uruchamiany, gdy użytkownik dwukrotnie kliknie wiersz.

  • Wykonaj ICommandSource i wywołaj CommandHelpers.ExecuteCommandSource(this) z dwukanałowego modułu obsługi zdarzeń.

Odpowiedz

10

Jeśli kod za to nie problem:

<DataGrid.RowStyle> 
    <Style TargetType="{x:Type DataGridRow}"> 
     <EventSetter Event="Loaded" Handler="Row_Loaded"/> 
    </Style> 
</DataGrid.RowStyle> 
private void Row_Loaded(object sender, RoutedEventArgs e) 
{ 
    var row = sender as DataGridRow; 
    row.InputBindings.Add(new MouseBinding(MyCommands.MyCommand, 
      new MouseGesture() { MouseAction = MouseAction.LeftDoubleClick })); 
} 
+0

Dziękuję +1 - to jest dokładnie to, co chcę osiągnąć, ale zastanawiałem się, czy istnieje deklaratywny sposób, aby to zrobić. – Joe

+0

Wątpię, czy jest prosta droga; można potokować zdarzenia do poleceń za pomocą funkcji "Interaktywność" z [Blend SDK] (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=f1ae9a30-4928-411d-970b-e682ab179e17&displaylang=en) i "EventToCommandAction", problem polega na tym, że używanie Interaktywności w stylu jest ** bardzo skomplikowane **, ale jeśli nie masz nic przeciwko problemowi [istnieją sposoby] (http://stackoverflow.com/questions/1647815/how- dodać-a-blend-zachowanie-w-stylu-seter/4779168 # 4779168). –

+0

@HB Właśnie dostaję się do MVVM i chcę KISS na teraz, więc myślę, że pójdę na rozwiązanie problemu kodu.Jedna uwaga dotycząca twojego rozwiązania - przypuszczalnie tworzenie MouseBinding dla każdego wiersza dodanego do DataGrid - czy może to być trochę nieefektywne, jeśli istnieje duża liczba wierszy? Jeśli wybieram trasę codebehind, zastanawiam się, czy lepiej byłoby obsłużyć zdarzenie DataGrid.MouseDoubleClick, przetestować test, aby upewnić się, że jestem w rzędzie, a następnie wykonać polecenie. – Joe

0

można po prostu umieścić DataGrid w siatce i zdefiniować InputBindings w siatce. W definicji canExecute należy sprawdzić, czy wybrany jest wiersz. Działa to również w KeyBinding, na przykład w niestandardowym poleceniu Delete.

<Grid> 
     <Grid.InputBindings> 
      <MouseBinding MouseAction="LeftDoubleClick" Command="... /> 
     </Grid.InputBindings> 
     <DataGrid IsReadOnly="True"> 
     ... 
</Grid> 
+0

Po dodaniu tej aplikacji zawiesza się. –

+0

Problem polega na tym, że można dwukrotnie kliknąć w dowolnym miejscu siatki, aby uruchomić polecenie po wybraniu wiersza, a nie tylko w samym wierszu. –

Powiązane problemy