MVVM-Light, запускающий события от кнопки внутри шаблона столбца сетки данных - PullRequest
9 голосов
/ 22 июля 2010

Свет MVVM было приятно изучать, но здесь я застрял. Проблема в событии.

В приведенном ниже коде одна кнопка запускает и запускает события. Другая кнопка не делает. Об ошибках привязки не сообщается в выходных данных. Есть ли что-то очевидное, чего мне не хватает?

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

Код модели представления:

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


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

Ответы [ 3 ]

11 голосов
/ 22 июля 2010

Ваш контекст данных теряется в DataGrid DataGridTemplateColumn, поскольку DataGrid.Columns не является свойством зависимости. Из-за этого вы не можете использовать привязку данных от элемента к элементу из вашего DataGridTemplateColumn.

Однако это легко исправить благодаря ViewModelLocator MVVM Light Toolkit.

Я не знаю, как называется ваша ViewModel, но, предполагая, что это MainViewModel, вы можете изменить привязку кнопки к этому:

<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 голосов
/ 18 ноября 2012

Это решение работает только для моделей со статическим представлением. проверьте страницу Дэна Валина для альтернативного ответа. http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

Вы можете создать такой ресурс (не забудьте ссылку):

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

или

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

Использовать в контроле так:

<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 Определить RelayCommand:

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

Установить RelayCommand в конструкторе:

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

                //DoSomething...
            }
        });
0 голосов
/ 22 июля 2010

Кнопка внутри DataGrid имеет DataContext из QuestActions, так как привязка основана на свойстве ItemSrid ItemGrid. В таком случае вам нужно найти DataContext самого DataGrid (или UserControl или любого другого родителя, который имеет Команду в своем DataContext), чтобы добраться до вашей Команды:

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