ContextMenu は DataGrid のビジュアル ツリーの一部ではないため、DataGrid の DataContext で定義されたプロパティにアクセスできません。しかし、それを行うための次の回避策を実行できます。
- 次のことを定義するためにブール型の添付プロパティを作成します。追加されたプロパティの値が true の場合、このプロパティがアタッチされているオブジェクトの視覚的な親を見つけ、このプロパティがアタッチされているオブジェクトの Tag プロパティに親の DataContext を割り当てます。添付プロパティが false の場合、Tag プロパティは null に割り当てられます。
- 呼び出し元のビジュアル ツリーをスキャンし、特定の型の (呼び出し元の) 親を返す拡張ヘルパー メソッドを作成します。
- 上記の依存関係プロパティを使用し、ContextMenu を定義する DataGridCell オブジェクトのデフォルト スタイルを作成します。このスタイルを App.xaml のリソースとして設定します (このスタイルはプロジェクト内のすべての DataGridCell オブジェクトで使用されることに注意してください)。
スタイル コード (App.xaml にある必要があります)
<Style TargetType="DataGridCell">
<Setter Property="dataGridCreateColumnAndBindIteFromCodeBehind:DataGridAttached.SetDataGridDataContextToTag" Value="True"></Setter>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="MenuItem One"
Command="{Binding CmdMenuItemOne}" />
<MenuItem Header="MenuItem Two"
Command="{Binding CmdMenuItemTwo}" />
</ContextMenu>
</Setter.Value>
</Setter></Style>
添付プロパティコード
public class DataGridAttached
{
public static readonly DependencyProperty SetDataGridDataContextToTagProperty = DependencyProperty.RegisterAttached(
"SetDataGridDataContextToTag", typeof (bool), typeof (DataGridAttached), new PropertyMetadata(default(bool), SetParentDataContextToTagPropertyChangedCallback));
public static void SetSetDataGridDataContextToTag(DependencyObject element, bool value)
{
element.SetValue(SetDataGridDataContextToTagProperty, value);
}
public static bool GetSetDataGridDataContextToTag(DependencyObject element)
{
return (bool) element.GetValue(SetDataGridDataContextToTagProperty);
}
private static void SetParentDataContextToTagPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
PerformDataContextToTagAssignment(dependencyObject as FrameworkElement, (bool)args.NewValue);
}
private static void PerformDataContextToTagAssignment(FrameworkElement sender, bool isAttaching)
{
var control = sender;
if (control == null) return;
if (isAttaching == false)
{
control.Tag = null;
}
else
{
var dataGrid = control.FindParent<DataGrid>();
if (dataGrid == null) return;
control.Tag = dataGrid.DataContext;
}
}
}
ヘルパー コード
public static class VisualTreeHelperExtensions
{
public static T FindParent<T>(this DependencyObject child) where T : DependencyObject
{
while (true)
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
child = parentObject;
}
}
}
よろしく。