[英]How to specify a DataContext whet adding the ContextMenu to the DataGridTemplateColumn?
我正在通過編程方式烹飪DataGridTemplateColumns
DataTemplate dtStringTemplate = (DataTemplate)XamlReader.Load(sr, pc); dataGridTemplateColumn.CellTemplate = dtStringTemplate;
我嘗試將ContextMenu添加到DataGrid,但是所有可編輯的單元格都使用了自己的上下文菜單。
到目前為止,這篇文章使我遠不如預期的那樣顯示TextBox上下文菜單: 如何在MVVM的WPF DataGridColumn中添加ContextMenu?
以上述文章為指導,我在App.xaml中創建了Style和ContextMenu。 當我右鍵單擊DataGrid中的Cell時,將出現上下文菜單。 但是,我無法啟動關聯的命令,並且我懷疑綁定不正確。 這是App.xaml中的xaml:
<ContextMenu x:Key="DataGridContextMenu">
<MenuItem Header="MenuItem One" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.CmdMenuItemOne}" />
<MenuItem Header="MenuItem Two" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.CmdMenuItemOne}" />
</ContextMenu>
DataGrid的DataContext是MyViewModel; MyViewModel具有一個名為CmdMenuItemOne的公共DelegateCommand。
不幸的是,CmdMenuItemOne從未被調用。
我對綁定有什么誤解? 謝謝 ...
使用下面給出的非常簡單的方法。
<Window.Resources>
<FrameworkElement x:Key="DCKey" />
</Window.Resources>
public MainWindow()
{
InitializeComponent();
this.DataContext = vm;
((FrameworkElement)this.Resources["DCKey"]).DataContext = vm;
}
<MenuItem Header="DoSomething" Command="{Binding DataContext.Cmd, Source={StaticResource DCKey}}"/>
由於ContextMenu不屬於DataGrid可視樹的一部分,因此我們無法訪問DataGrid的DataContext中定義的屬性。 但是我們可以執行下一個解決方法。
樣式代碼(應位於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;
}
}
}
問候。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.