2010-07-22 8 views
9

La luz MVVM ha sido un placer de aprender, pero aquí estoy atascado. El problema es el lanzamiento de eventos.MVVM-Light, eventos de encendido desde un botón dentro de una plantilla de columna de cuadrícula de datos

En el siguiente código, un botón ejecuta y desencadena eventos. El otro botón no. No se informan errores de enlace en la salida. ¿Hay algo obvio que me estoy perdiendo?

<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> 

código de modelo de vista:

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


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

Respuesta

9

Su contexto de datos se pierde en DataGrid DataGridTemplateColumn dado que DataGrid.Columns no es una propiedad de dependencia. Debido a esto, no puede usar el enlace de datos de elemento a elemento desde su DataGridTemplateColumn.

Sin embargo, esto se soluciona fácilmente gracias al ViewModelLocator de MVVM Light Toolkit.

No sé cuál es su modelo de vista se llama, pero asumiendo que es MainViewModel Puede cambiar su unión a este botón:

<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

¡Eso es precisamente lo que necesitaba! Gracias, y con eso, MVVM-light sigue siendo un enfoque simple y elegante para Silverlight en todos los escenarios. Gracias de nuevo – nachonachoman

+0

¿Funciona esto también en Silverlight o solo funciona en WPF? – Radhi

+0

Este ejemplo fue creado en Silverlight, no en WPF. –

0

El botón dentro de la cuadrícula de datos tiene un DataContext de QuestActions ya que la unión se basa en la cuadrícula de datos de la ItemSource propiedad. Siendo ese el caso, usted tendrá que encontrar el DataContext de la misma cuadrícula de datos (o el control de usuario o cualquier padre que tiene el Comando en que es DataContext) para llegar a su Comando:

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

me corrija si estoy equivocado, pero no son la FindAncestor y cositas AncestorType sólo está disponible en WPF? –

+0

Aunque la teoría es correcta, debe vincularse al DataContext del ParentGrid primario. En este hilo hay una solución alternativa que quizás quiera consultar: http://forums.silverlight.net/forums/p/163476/367975.aspx –

+0

¿De verdad? No me di cuenta de que FindAncestor y AncestorType eran solo WPF. –

0

Esta solución sólo funciona para los modelos de vista estático. echa un vistazo a la página de Dan Whalin para obtener una respuesta alternativa. http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

Puede crear un recurso como tal (no se olvide su referencia):

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

o

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

uso en el control de este 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> 

modelo de vista Definir RelayCommand:

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

Conjunto RelayCommand en el constructor:

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

       //DoSomething... 
      } 
     }); 
Cuestiones relacionadas