2012-02-28 60 views
7

我想在双击事件后从数据网格中检索行信息。我有事件设置,但现在我只需要设置函数来检索行中的数据。双击后获取行信息

XAML:

<DataGrid 
     Width="Auto" 
     SelectionMode="Extended" 
     IsReadOnly="True" 
     Name="ListDataGrid" 
     AutoGenerateColumns="False" 
     ItemsSource="{Binding ListFieldObject.MoviesList}" 
     DataContext="{StaticResource MovieAppViewModel}" 
     cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect()]"> 

     <DataGrid.Columns> 
      <DataGridTextColumn Width="200" IsReadOnly="True" Header="Title" Binding="{Binding Title}"/> 
      <DataGridTextColumn Width="100" IsReadOnly="True" Header="Rating" Binding="{Binding Rating}"/> 
      <DataGridTextColumn Width="100" IsReadOnly="True" Header="Stars" Binding="{Binding Stars}"/> 
      <DataGridTextColumn Width="93" IsReadOnly="True" Header="Release Year" Binding="{Binding ReleaseYear}"/> 
     </DataGrid.Columns> 
    </DataGrid> 

C#(MVVM视图模型):

 public void RowSelect() 
    { 
     //now how to access the selected row after the double click event? 
    } 

谢谢了!

+0

从我可以告诉它是非常困难的,如果不是不可能的。很多网站都在讨论这个问题,例如http://www.scottlogic.co。uk/blog/colin/2008/12/wpf-datagrid-detection-clicked-cell-and-row/and this http://stackoverflow.com/questions/5808616/how-to-bind-a-command-to-双击在行数据网格 – Phil 2012-02-28 20:29:06

回答

6

随着卡利这是很容易,只是传递$的DataContext你的XAML:

cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect($dataContext)]"> 

,改变你的方法:

public void RowSelect(MoviesListItem movie) 
{ 
    //now how to access the selected row after the double click event? 
} 

//编辑 很抱歉,如果动作是在DataTemplate中自身上述方案将只工作...另一个解决办法是有一个的SelectedItem绑定,只是用它在你的方法:

<DataGrid 
    SelectedItem="{Binding SelectedMovie,Mode=TwoWay}" 
    cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect()]"> 

,并在你的代码:

public void RowSelect() 
{ 
    //SelectedMovie is the item where the user double-cliked 
} 
+0

这就是我最终做到的。谢谢您的帮助! – Josh 2012-02-29 19:05:06

+0

该解决方案是可行的,但从经验来看,如果用户快速点击数据网格的某些区域,则会有不可预知的行为。最值得注意的例子:用户喜欢在垂直滚动条中快速点击向下箭头或拇指轨迹,如果他们正在滚动大型列表。 许多用户不会单击并拖动拇指进行滚动;相反,他们在箭头或拇指轨道上捶打。此解决方案总是会导致双击执行,因为它由数据网格处理而不是数据行处理。 – Adrian 2012-03-01 16:47:20

+0

@Josh,这个解决方案也会处理列标题的双击,这几乎没有必要。为了防止这种情况,请考虑* David Kiff * bellow的解决方案。 – Sevenate 2014-01-22 10:02:21

1

(希望这将有助于)我不知道你的情况,但是这是我做的WinForms:

  int index = dataGridView2.CurrentRow.Index; //determine which item is selected 
      textBox8.Text = dataGridView2.Rows[index].Cells[0].Value.ToString(); //add login 
+0

你输入赞赏,但我使用MVVM模式,不能在代码后面的调用。我将编辑原始帖子以反映C#在ViewModel中的事实。 – Josh 2012-02-28 18:06:50

1

您可以通过修改DataGrid公开的DataGridRows的控件模板来实现。下面的例子使用WPF和Aero主题。

我所做的唯一的事情就是删除以前的cal:Message.Attach调用,并将它移动到一个新的“占位符”ContentControl,该对象围绕着默认控件模板中的Border(x:Name = DGR_Border)。 (我用ContentControl中,因为它没有自己的视觉效果,它暴露了一个MouseDoubleClick事件。)

<DataGrid Width="Auto" 
      SelectionMode="Extended" 
      IsReadOnly="True" 
      Name="ListDataGrid" 
      AutoGenerateColumns="False" 
      ItemsSource="{Binding ListFieldObject.MoviesList}" 
      DataContext="{StaticResource MovieAppViewModel}"> 

    <DataGrid.Columns> 
     <DataGridTextColumn Width="200" IsReadOnly="True" Header="Title" Binding="{Binding Title}"/> 
     <DataGridTextColumn Width="100" IsReadOnly="True" Header="Rating" Binding="{Binding Rating}"/> 
     <DataGridTextColumn Width="100" IsReadOnly="True" Header="Stars" Binding="{Binding Stars}"/> 
     <DataGridTextColumn Width="93" IsReadOnly="True" Header="Release Year" Binding="{Binding ReleaseYear}"/> 
    </DataGrid.Columns> 
    <DataGrid.RowStyle> 
     <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 
     <Setter Property="SnapsToDevicePixels" Value="true"/> 
     <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/> 
     <Setter Property="ValidationErrorTemplate"> 
      <Setter.Value> 
       <ControlTemplate> 
        <TextBlock Foreground="Red" Margin="2,0,0,0" Text="!" VerticalAlignment="Center"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value>          
       <ControlTemplate TargetType="{x:Type DataGridRow}"> 
        <ContentControl cal:Message.Attach="[Event MouseDoubleClick] = [Action RowSelect($datacontext)]"> 
         <Border x:Name="DGR_Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> 
          <SelectiveScrollingGrid> 
           <SelectiveScrollingGrid.ColumnDefinitions> 
            <ColumnDefinition Width="Auto"/> 
            <ColumnDefinition Width="*"/> 
           </SelectiveScrollingGrid.ColumnDefinitions> 
           <SelectiveScrollingGrid.RowDefinitions> 
            <RowDefinition Height="*"/> 
            <RowDefinition Height="Auto"/> 
           </SelectiveScrollingGrid.RowDefinitions> 
           <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
           <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Visibility="{TemplateBinding DetailsVisibility}"/> 
           <DataGridRowHeader Grid.RowSpan="2" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/> 
          </SelectiveScrollingGrid> 
         </Border> 
        </ContentControl> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </DataGrid.RowStyle> 
</DataGrid> 

你必须做的唯一的另一件事就是修改RowSelect()方法接受的任何参数你在这里使用的类型(我只是假设它是'电影'类型)。

public void RowSelect(Movie movie) 
{ 
    // do something with 'movie' 
} 
0

我的例子中有一个名为“service_id”的列。但是你也可以使用int32列的偏移量。 DataRowView类型中甚至有一个ItemArray可以运行和关闭。请参阅System.Data命名空间。 您的Datagrid itemssource/context会影响您在Datagrid中看到的“对象”。但是,如果您检查调试类型,那么您可以投它们并使用它们。

private void DataGridServiceRegistry_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    DataGrid DGSR = (DataGrid) sender; 
    var SR = (DataRowView) DGSR.CurrentItem; 
    var service_id = SR.Row["SERVICE_ID"]; 
} 
17

您也可以做到这一点:

<DataGrid> 
    <DataGrid.RowStyle> 
     <Style TargetType="DataGridRow"> 
      <Setter Property="cal:Message.Attach" Value="[MouseDoubleClick] = [Action RowSelect($dataContext)]"/> 
     </Style> 
    </DataGrid.RowStyle> 
</DataGrid> 

然后

public void RowSelect(MoviesListItem movie) 
{ 
    //now how to access the selected row after the double click event? 
} 
+2

这是更好的解决方案,然后接受答案,因为它只捕获双击行而不是头。 – Sevenate 2014-01-22 09:56:21

+1

这是我一直在寻找的答案,应该标记为答案。 – 2015-11-12 09:51:11