在DataGrid中设置命令

时间:2013-03-28 11:51:18

标签: wpf xaml datagrid

我想放入DataGrid的单元格ListBox按钮。我在GoogleGrid上搜索但只发现了两件事:

  1. 使用DataGridTemplateColumn并在模板中设置命令
  2. 使用DataGridHyperLinkColumn并设置事件处理程序
  3. 我尝试了第一个变体(当我点击按钮时,没有任何反应,如果我使用它而没有ListBox仅作为Button):

    <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <ListBox ItemsSource="{Binding diffs}">
                                            <ListBox.ItemTemplate>
                                                <DataTemplate>
                                                    <Button Command="{Binding ElementName=Root, 
                                                            Path=DataContext.viewSimpleRoute, Mode=OneTime}"
                                                            CommandParameter="{Binding}">
                                                    aaa
                                                </Button>
    
                                                </DataTemplate>
                                            </ListBox.ItemTemplate>
                                        </ListBox>
    

    第二个变体对我不可用,因为我想在DataGrid的单元格中创建几个命令绑定(或事件处理程序)。这样我只能重写DataGridHyperlinkColumn.ElementStyle的样式并只设置一个事件处理程序(因为我知道我不能在这里设置命令)。


    更新

     <DataTemplate DataType="{x:Type tdm:TVZ+SimpleTvzDiffModel}">
    
                    <StackPanel Orientation="Vertical">
                        <Button Width="100" Height="23" 
                                                Command="{Binding ElementName=Root, Path=DataContext.viewSimpleRoute, Mode=OneTime}"
                                                CommandParameter="{Binding}">
                            WORKS
                        </Button>
                        <DataGrid ItemsSource="{Binding diffRoutes}" AutoGenerateColumns="False">
                            <DataGrid.Columns>                            
                                <DataGridTemplateColumn Header="Маршруты">
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <Button Width="100" Height="23" 
                                                Command="{Binding ElementName=Root, Path=DataContext.viewSimpleRoute, Mode=OneTime}"
                                                CommandParameter="{Binding}">
                                                DOES NOT WORK
                                            </Button>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                </DataGridTemplateColumn>
    

    为什么呢?

2 个答案:

答案 0 :(得分:0)

使用RelayCommand将Button绑定到ViewModel 为了简化解决方案,我只是放出ViewModel并在Window本身中编写了Propertys。 你应该考虑改变它。

Class MainWindow

      Public Property diffs As List(Of String)
      Public Property ButtonCommand As New RelayCommand(AddressOf ButtonClick)

      Private Sub ButtonClick()
      End Sub

End Class


XAML代码:
(我使用DataGrid.ItemsSource的差异以及ListBox.ItemsSource的差异来简化它。

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" 
    x:Name="Root">
  <Grid>
    <DataGrid x:Name="DataGridButtons" ItemsSource="{Binding ElementName=Root, Path=diffs}">
      <DataGrid.Columns>
        <DataGridTemplateColumn>
          <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <ListBox ItemsSource="{Binding ElementName=Root, Path=diffs}">
                <ListBox.ItemTemplate>
                  <DataTemplate>
                    <Button Width="100" Height="23" Command="{Binding ElementName=Root, Path=ButtonCommand, Mode=OneTime}" CommandParameter="{Binding}">aaa</Button>
                  </DataTemplate>
                </ListBox.ItemTemplate>
              </ListBox>
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</Window>



接力指令类的来源:

Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Windows.Input
Imports System.Diagnostics

Public Class RelayCommand
    Implements ICommand

    ReadOnly _execute As Action(Of Object)
    ReadOnly _canExecute As Predicate(Of Object)

    Public Sub New(execute As Action(Of Object))
        Me.New(execute, Nothing)
    End Sub

    Public Sub New(execute As Action(Of Object), canExecute As Predicate(Of Object))
        If execute Is Nothing Then
            Throw New ArgumentNullException("execute")
        End If

        _execute = execute
        _canExecute = canExecute
    End Sub

    <DebuggerStepThrough()> _
    Public Function CanExecute(parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
        Return If(_canExecute Is Nothing, True, _canExecute(parameter))
    End Function

    Public Sub Execute(parameter As Object) Implements System.Windows.Input.ICommand.Execute
        _execute(parameter)
    End Sub

    Public Sub UpdateCanExecute()
        RaiseEvent CanExecuteChanged(Me, New EventArgs())
    End Sub

    Public Sub RaiseCanExecuteChanged()
        CommandManager.InvalidateRequerySuggested()
    End Sub

    ''' <summary>
    ''' To prevent the following calls to invalidate the CanExecuteProperty
    ''' StartCommand.RaiseCanExecuteChanged()
    ''' StopCommand.RaiseCanExecuteChanged()
    ''' </summary>
    ''' <remarks></remarks>
    Public Custom Event CanExecuteChanged As EventHandler Implements System.Windows.Input.ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler CommandManager.RequerySuggested, value
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        End RaiseEvent
    End Event

    'Public Event CanExecuteChanged(sender As Object, e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged

End Class

答案 1 :(得分:0)

我做了一些非常类似于@BastiOnWpf的事情,但在xaml中略有改变,如下所示;

<UserControl.Resources>
    <DataTemplate x:Key="RowButtons">
        <StackPanel Orientation="Horizontal">
            <Button Content="SomeCommand" Command="{Binding SomeCommand}" Width="50"/>
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>

        <ListView Name="ListView" Height="70" Width="700"
                  ItemsSource="{Binding diffs}">
            <ListView.View>
                <GridView>
                    <GridViewColumn CellTemplate="{StaticResource RowButtons}"/>
                    <!-- Rows goes here-->
                </GridView>
            </ListView.View>
        </ListView>

正如您所看到的,在我的资源中,我已经设置了datatemplate,您希望能够在listbox中添加命令。

视图模型;

        private ICommand _Command;
        public ICommand SomeCommand
        {
            get
            {
                if (this._Command == null)
                {
                    this._Command = new new RelayCommand(this.SomeMethod); //The method/procedure you want to use for the listbox
                }
                return this._Command;
            }
        }

我还使用了RelayCommand,您可以看到我bind从视图模型到视图的项目。

希望这会有所帮助:)。