Silverlight DataGrid中获取ContextMenu的Owner的DataContext
这篇博文的题目不是很好取,想了半天只能取这么绕口的一个名字。
写这篇文章的情形是这样的:
我有一个DataGrid,自定义了它的DataTemplate,并且在每一个Data上都附加了一个右键菜单(ContextMenu),如下
public class MyText
{
public string MyTextString { get; set; }
}
<sdk:DataGrid x:Name="Test1DataGrid" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Width="1*" Header="Column1">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MyTextString}">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Copy Text" Click="Copy_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
现在存在一个问题,我的右键菜单中MenuItem的点击函数Copy_Click需要调用到它所在的那一个Cell的TextBlock的Text。也就是我的右键菜单中希望把TextBlock中的Text复制到剪切板中。
但是这个Text应当怎样获得呢?
我在调试的时候发现可以看到Owner属性:如下
((ContextMenu)((MenuItem)sender).Parent).Owner
它可以指向这个ContextMenu所在的TextBlock,我以为我就可以拿到了。实际上不然,这个Owner属性不是public的,看的着拿不着。
怎么办呢?
我试着查看了((ContextMenu)((MenuItem)sender).Parent)所有的属性,发现DataContext居然就是这个Cell绑定到的那个实例,即
((ContextMenu)((MenuItem)sender).Parent).DataContext as MyText
这个就是我想要的了,不需要先找到TextBlock,而是直接拿到绑定到TextBlock上的实例,轻松搞定!
后来我又尝试了下面的代码
((MenuItem)sender).DataContext as MyText
居然也是可以的,拿到的实例一模一样!
所以我在想,可能是DataGrid,ListBox等有ItemsSource的控件在生成每一行的时候把每个Cell的所有组成部分的DataContext都指向了这一行实例。