【问题标题】:Button Command not binding to ViewModel in DatGrid按钮命令未绑定到 DataGrid 中的 ViewModel
【发布时间】:2011-09-17 02:36:35
【问题描述】:

我有 ViewModel,它有一个 ObservableCollection[Employee] EmpCol,现在 ViewModel 与我的 View 绑定,并且 EmpCol 设置为与自定义控件的 ItemSource 一样。该自定义控件生成带有网格的堆栈面板,如果 EmpCol 中有 4 个对象,则其中将有 4 个带有网格的堆栈面板。现在在这些网格中,我有一列按钮。 现在我的问题是我无法将数据网格中该按钮的命令绑定到 Employee 类中的 RelayCommand。

我正在使用 MVVM 轻量级工具包,我找到了一种方法,实际上可以为这样的绑定命令提供完整路径

<Button x:Name="myButton"  Width="20" Height="15" HorizontalAlignment="Center"   VerticalAlignment="Center" Margin="5" >   
<i:Interaction.Triggers>
 <i:EventTrigger EventName="Click"> 
<cmd:EventToCommand Command="{Binding Source={StaticResource VMLocator}, Path=MyVM.Employee.MyButtonCommand}" PassEventArgsToCommand="False"/>  </i:EventTrigger>
</i:Interaction.Triggers>
</Button>

现在上述方法有效,但在我的情况下,我没有 Employee ,而是 Employee 集合,所以当我给出这样的绑定路径时 Path=MyVM.EmpCol.MyButtonCommand

它不起作用。我搜索了很多,但找不到任何解决方案。 因此,我们将不胜感激任何帮助来解决我的问题。

谢谢, 特立独行

命令绑定发生在 DataGrid 的一行内。

【问题讨论】:

    标签: silverlight mvvm binding command mvvm-light


    【解决方案1】:

    最简单的方法是使用中继命令,例如

    public RelayCommand SearchCommand
     {
        get
        {
          return new RelayCommand(GetData);//GetDatais a method for your action on click event
        }
    }
    

    详情请见以下链接

    http://codenicely.blogspot.com/2012/01/handling-button-click-event-in.html

    【讨论】:

      【解决方案2】:

      解决方案取决于您的视图的结构,如果您有一个主详细信息视图,您应该创建一个子结构,该子结构需要一个员工 ViewModel 作为 DataContext 并将其绑定到当前选定的员工。这样您就可以为您的视图获得正确的 ViewModel。

      如果您导航到新页面,最简单的方法可能是将 View 传递给您要显示的员工的 id,然后在后面的代码中调用视图模型上的方法 - 您可以从 DataContext 属性中获取- 从数据库或服务中加载正确的员工。

      或者,您可以将当前员工保存在应用程序范围的可访问变量中。例如。应用程序类上的静态变量、存储在资源中或 ViewLocator 上的单例或静态类(在所有情况下,当没有选择员工或阻止打开视图时,您可能必须提供一个空的员工 ViewModel)。

      编辑

      如果 ViewModel 的集合绑定到 DataGrid 并且命令的绑定存在问题,这可能是一个可能的解决方案:

      将命令放在包含集合的 ViewModel 上(即绑定到 DataGrid 的 ItemsSource 的属性)。然后在这个高级 ViewModel 上执行命令。您现在可以使用 RelativeSurce 绑定通过 DataGrid 的父 DataContext 属性访问这个更高级别的 ViewModel。在您的按钮中,您现在可以绑定命令并将当前行的 DataContext 作为命令参数传递 - 命令显然必须期待这个参数。

      编辑 2

      Forgot Silverlight 不支持所有的 RelativeSource 模式,但是,它支持绑定到命名元素,因此以下应该可以工作...

      假设:

      1. 更高级别的 ViewModel 称为“EmployeeListViewModel”
      2. 它有一个名为Employees 的属性,其中包含EmployeeViewModels 列表
      3. 包含 DataGrid 的元素的 DataContext 设置为 EmployeeListViewModel

      代码:

      <DataGrid x:Name="dgEmployees" ItemsSource="{Binding Empoyees}" ...>
          ...
              <Button x:Name="myButton"  Width="20" Height="15" HorizontalAlignment="Center" 
                      VerticalAlignment="Center" Margin="5" >   
                  <i:Interaction.Triggers>
                      <i:EventTrigger EventName="Click"> 
                          <cmd:EventToCommand 
                              Command="{Binding ElementName=dgEmployees, Path=DataContext.MyButtonCommand}" 
                              CommandParameter="{Binding}" 
                              PassEventArgsToCommand="False"/>
                  </i:Interaction.Triggers>
              </Button>
          ...
      </DataGrid>
      

      【讨论】:

      • Obalix,问题在于该数据网格内的按钮绑定。我的 datagrid 的 Itemsource 是 'Employee' 类中的一个集合属性,并且 datagrid 的所有事件也正确绑定到我的 Employee 类中的 RelayCommands 。只有当我进入数据网格并从那里尝试将 Relaycomand 绑定到按钮时才会出现问题,它在那里丢失了它的数据上下文。
      • 这是一个已知的 datagrid 中的按钮绑定问题,通常解决方案是使用静态 datatcontext ,但在我的问题中,Employee 类在一个集合中,并且该集合是我的视图模型中的一个属性,所以静态数据上下文在我的情况下不起作用。
      • @Maverick:在您的原始帖子中,您没有提到您正在使用 DataGrid - 您只是在谈论“网格”。但是,我编辑了帖子以包含可能解决您的问题的解决方案。
      • 是的,我没有说 datagrid ,但我的意思是 datagrid。我在 web 上查看了 RelativeSource,看来你只能给出两个值 'TemplatedParent' 或 'self' ,但我认为你建议使用放置按钮的数据网格的名称,不是吗?你能详细说明一下吗?
      • @Maverick:抱歉忘记我们在谈论 Silverlight。但请参阅第二次编辑以获取可能的解决方案。
      猜你喜欢
      • 2012-02-23
      • 2020-02-27
      • 2020-05-28
      • 2012-02-17
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      相关资源
      最近更新 更多