2010-07-22 9 views
9

MVVM light è stato un piacere apprendere, ma qui sono bloccato. Il problema è l'attivazione degli eventi.MVVM-Light, eventi di attivazione da un pulsante all'interno di un modello di colonna della griglia di dati

Nel codice sottostante, un pulsante funziona e attiva gli eventi. L'altro pulsante non lo fa. Nessun errore di associazione viene segnalato nell'output. C'è qualcosa di ovvio che mi manca?

<Grid x:Name="LayoutRoot">... 
<StackPanel> 
    <Button Content="THIS BUTTON WORKS"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Click"> 
     <Command:EventToCommand Command="{Binding DataContext.HandleAddQuestionActionCommand, ElementName=LayoutRoot, Mode=OneWay}" PassEventArgsToCommand="True"/> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    </Button> 
    <sdk1:DataGrid ItemsSource="{Binding QuestionActions}" AutoGenerateColumns="False" > 
    <sdk1:DataGrid.Columns> 
     <sdk1:DataGridTextColumn Binding="{Binding Answer.Name}" Header="Answer"/> 
     <sdk1:DataGridTemplateColumn Header="Edit"> 
      <sdk1:DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <Button Content="THIS BUTTON DONT WORK" > 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Click"> 
        <Command:EventToCommand Command="{Binding DataContext.HandleEditQuestionActionCommand, ElementName=LayoutRoot, Mode=OneWay}" PassEventArgsToCommand="True"/> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
       </Button> 
      </DataTemplate> 
      </sdk1:DataGridTemplateColumn.CellTemplate> 
     </sdk1:DataGridTemplateColumn> 
    </sdk1:DataGrid.Columns> 
    </sdk1:DataGrid> 
</StackPanel> 

codice ViewModel:

public RelayCommand<RoutedEventArgs> HandleAddQuestionActionCommand { 
    get; private set; 
} 
public RelayCommand<RoutedEventArgs> HandleEditQuestionActionCommand { 
    get; private set; 
} 


HandleAddQuestionActionCommand = new RelayCommand<RoutedEventArgs>(e =>{...}); 
HandleEditQuestionActionCommand = new RelayCommand<RoutedEventArgs>(e =>{...}); 

risposta

9

vostro contesto dati viene perso in DataGrid DataGridTemplateColumn poiché DataGrid.Columns non è una proprietà di dipendenza. Per questo motivo, non è possibile utilizzare l'associazione dati elemento-elemento dall'interno di DataGridTemplateColumn.

Tuttavia, questo problema viene risolto facilmente grazie a ViewModelLocator di MVVM Light Toolkit.

Non so che cosa il vostro ViewModel si chiama, ma ammesso che sia MainViewModel è possibile modificare il pulsante di legame a questo:

<sdk1:DataGridTemplateColumn Header="Edit"> 
    <sdk1:DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <Button Content="THIS BUTTON WILL WORK NOW ;-)" > 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Click"> 
         <Command:EventToCommand Command="{Binding Source={StaticResource Locator}, 
                    Path=MainViewModel.HandleEditQuestionActionCommand}" 
               PassEventArgsToCommand="True" /> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
      </Button> 
     </DataTemplate> 
    </sdk1:DataGridTemplateColumn.CellTemplate> 
</sdk1:DataGridTemplateColumn> 
+0

Questo è esattamente ciò di cui avevo bisogno! Grazie, e con questo, MVVM-light continua ad essere un approccio semplice ed elegante alla Silverlight in tutti gli scenari. Grazie ancora – nachonachoman

+0

Funziona anche con Silverlight o funziona solo con WPF? – Radhi

+0

Questo esempio è stato creato in Silverlight, non in WPF. –

0

Il pulsante all'interno del DataGrid ha un DataContext di QuestActions dal momento che la rilegatura è basato sul del DataGrid ItemSource Proprietà. Stando così le cose, è necessario trovare il DataContext del DataGrid stessa (o l'UserControl o qualunque genitore che ha il comando nella sua DataContext) per arrivare al tuo comando:

<Command:EventToCommand 
Command="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type sdk1:DataGrid}}, 
Path=DataContext.ViewSchemaCommand, Mode=OneWay}" 
PassEventArgsToCommand="True" /> 
+1

mi corregga se sbaglio, ma non sono la FindAncestor e thingies AncestorType disponibile solo in WPF? –

+0

La teoria è corretta, tuttavia, è necessario eseguire il binding al DataContext del padre DataGrid. In questo thread è una soluzione alternativa che potrebbe essere utile: http://forums.silverlight.net/forums/p/163476/367975.aspx –

+0

Davvero? Non avevo realizzato che FindAncestor e AncestorType fossero solo WPF. –

0

questa soluzione funziona solo per i modelli visione statica. controlla la pagina di Dan Whalin per una risposta alternativa. http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

È possibile creare una risorsa in questo modo (non dimenticate il vostro riferimento):

<UserControl.Resources> 
    <controls:DataContextProxy x:Key="DataContextProxy" /> 
</UserControl.Resources> 

o

<sdk:Page.Resources> 
    <controls:DataContextProxy x:Key="DataContextProxy"/> 
</sdk:Page.Resources> 

Usa in controllo in questo modo:

<sdk:DataGridTemplateColumn> 
<sdk:DataGridTemplateColumn.CellTemplate> 
    <DataTemplate> 
     <Button Content="Content"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="Click"> 
        <cmd:EventToCommand Command="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.MyCommand}" 
             CommandParameter="{Binding Path=SomeValue}" 
             PassEventArgsToCommand="False">  
        </cmd:EventToCommand> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </Button> 
    </DataTemplate> 
</sdk:DataGridTemplateColumn.CellTemplate> 

ViewModel Definire RelayCommand:

public RelayCommand<object> MyCommand { get; set; } 

Set RelayCommand nel costruttore:

MyCommand = new RelayCommand<object>((e) => 
     { 
      if (e != null && e is int) 
      { 
       int varName = int.Parse(e.ToString()); 

       //DoSomething... 
      } 
     }); 
Problemi correlati