代码之家  ›  专栏  ›  技术社区  ›  nachonachoman

MVVM灯,从数据网格列模板中的按钮触发事件

  •  9
  • nachonachoman  · 技术社区  · 16 年前

    在下面的代码中,一个按钮可以工作并触发事件。另一个按钮没有。输出中未报告任何绑定错误。我有什么明显的遗漏吗?

    <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 回复  |  直到 16 年前
        1
  •  11
  •   Matt Casto    16 年前

    您的数据上下文在DataGrid DataGridTemplateColumn中丢失,因为DataGrid.Columns不是依赖项属性。因此,不能在DataGridTemplateColumn中使用元素到元素的数据绑定。

    不过,由于MVVMLightToolkit的ViewModelLocator,这个问题很容易解决。

    我不知道您的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>
    
        2
  •  0
  •   Metro Smurf    16 年前

    DataGrid中的按钮具有QuestActions的DataContext,因为绑定基于DataGrid的ItemSource属性。在这种情况下,您需要找到DataGrid本身的DataContext(或UserControl或在其DataContext中包含命令的任何父级)才能访问您的命令:

    <Command:EventToCommand 
    Command="{Binding RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type sdk1:DataGrid}}, 
    Path=DataContext.ViewSchemaCommand, Mode=OneWay}" 
    PassEventArgsToCommand="True" />
    
        3
  •  0
  •   pwDev    13 年前

    此解决方案仅适用于静态视图模型。查看丹·惠林的网页,寻找另一个答案。 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>
    

    视图模型

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

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