2013-03-12 63 views
7

基本上我已经绑定了数据网格,因此它类似于科目的时间表 - 每一行代表一学期的科目,并且该学期内的每个单元格代表一个科目。如何在代码中访问DataGridCell的数据对象?

我现在试图添加拖放功能,以便您可以将其他主题拖动到网格上,这将更新基础数据结构。

我可以使用一些可视化树方法来查找用户拖动新主题的DataGridCell,但我不知道如何访问单元格绑定到的值(主题)以便用新主题替换空白/占位符值。有没有办法访问底层的价值,还是我应该重构我创建这个程序的整个方法?

An example of the grid and the subjects to be dragged onto it

+0

你可以粘贴网格结构吗? – Freelancer 2013-03-12 12:47:14

+0

物理GridView或底层结构? – Miguel 2013-03-12 12:48:10

+0

只是列和实用数据 – Freelancer 2013-03-12 12:49:09

回答

3

为了得到DataGridCell的数据,你可以用它的DataContext和Column财产。如何做到这一点完全取决于你的行数据,即你在DataGrid的ItemsSource集合中放置了哪些项目。假设你的项目object[]阵列:

// Assuming this is an array of objects, object[],this gets you the 
// row data as you have them in the DataGrid's ItemsSource collection 
var rowData = (object[]) DataGrid.SelectedCells[0].Item; 
// This gets you the single cell object 
var celldata = rowData[DataGrid.SelectedCells[0].Column.DisplayIndex]; 

如果你的行中的数据比较复杂,你需要写一个翻译上的行数据项Column属性和行数据项的具体值的相应的方法。


编辑:

如果你把你的数据到是不是所选单元格的单元格,一种选择是让DataGridRow到该DataGridCell属于使用VisualTreeHelper

var parent = VisualTreeHelper.GetParent(gridCell); 
while(parent != null && parent.GetType() != typeof(DataGridRow)) 
{ 
    parent = VisualTreeHelper.GetParent(parent); 
} 
var dataRow = parent; 

然后你有这一行,并可以按照上述进行。


此外,关于你的问题,你是否应该重新考虑的方法,我会建议使用自定义WPF行为秒。

行为提供了一种非常直接的方式来从C#代码扩展控件的功能,而不是XAML,但保持代码隐藏清晰和简单(如果您遵循MVVM,这不仅很好)。行为的设计方式是可重复使用的,并不受限于您的特定控制。

Here's a good introduction

对于你的特殊情况下,我只能给你做什么的想法:

写一个DropBehavior您的TextBlock控件(或任何控制你希望你的DataGridCells,该手柄内下降。其基本思路是根据你的控制OnAttached()方法行动细胞的EVNT注册。

public class DropBehavior : Behavior<TextBlock> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.MouseUp += AssociatedObject_MouseUp; 
    } 

    private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     // Handle what happens on mouse up 

     // Check requirements, has data been dragged, etc. 
     // Get underlying data, now simply as the DataContext of the AssociatedObject 
     var cellData = AssociatedObject.DataContext; 

    } 
} 

需要注意的是,解析单细胞的数据来回回行数据和Column属性变得过时。

然后您将这个行为的TextBlocks,你你的细胞里面放,使用DataGrid的CellStyleContentTemplate

<DataGrid> 
    <DataGrid.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <TextBlock Text="{Binding}"> 
          <i:Interaction.Behaviors> 
           <yourns:DropBehavior/> 
          </i:Interaction.Behaviors> 
         </TextBlock> 
        </DataTemplate> 
       </Setter.Value> 

      </Setter> 
     </Style> 
    </DataGrid.CellStyle> 
</DataGrid> 

您可以找到Behavior<T>基类中

系统.Windows.Interactivity.dll

我还没有测试过,但我希望它为你工作,你会明白...

+0

我会看看WPF行为的事情,谢谢你的链接。然而,对于你的答案的第一部分,我不能做你的任何解决方案。在第一个例子中,你使用DataGrid.SelectedCells [0],它返回一个DataGridCellInfo,我*没有*。记住我只有DataGridCell,它是在拖放之后从鼠标位置获得的,我没有选择。我可以选择这个单元格,然后执行此方法,但我宁愿不必更改用户的选择。 – Miguel 2013-03-13 00:40:48

+0

在第二种方法中,您使用rowData [Column Index]。我可以得到列索引,因为我有列(它是DataGridCell的一个属性),但我不知道单元格的当前行以获得正确的rowData结构。 – Miguel 2013-03-13 00:41:21

+0

@Miguel:我点了我的帖子。我肯定会推荐使用行为。这真的没有那么复杂,而且所有这些寻找父行和铸造的东西都不是很好的风格和效率。 – Marc 2013-03-13 08:42:36

相关问题