1. 程式人生 > 其它 >wpf-mvvm開發學習3 關於ContextMenu的DataContext繫結

wpf-mvvm開發學習3 關於ContextMenu的DataContext繫結

在MVVM模式下 關於ContextMenu的DataContext繫結問題

參考連結:

https://blog.csdn.net/WPwalter/article/details/83473313

https://blog.csdn.net/Backspace110/article/details/109630129

情景

xaml結構

我為Grid指定了一個DataContext

希望Listboxitem的ContextMenu也使用該DataContext

希望將選單項繫結到viewmodel的命令上

但是繫結總是失敗 DataContext並不符合預期

查詢原因是ContextMenu並不存在於視覺化樹中

如下圖 繫結是失敗的 VS認為繫結到了Model 而我們的命令介面在viewmodel

所以解決方案應該是讓binding指向正確的路徑

解決方案

為該Grid指定名字

並建立資源用於代理

<Grid.Resources>
    <DiscreteObjectKeyFrame x:Key="proxy" Value="{x:Reference Name=processmangergrid}" />
</Grid.Resources>

接下來再指定ContextMenu的DataContext

<ContextMenu DataContext="{Binding Source={StaticResource proxy}, Path=Value.DataContext}">
    <MenuItem Command="{Binding Path=RefeshProcessCommand}" Header="重新整理程序" />
</ContextMenu>

關於該ContextMenu的引數傳遞問題

還是常規操作

viewmodel中先定義該命令介面

public ICommand KillProcessItemCommand { get; }
void KillProcessItemExecute(ListBoxItem tItem)
{
    //函式功能實現
}
//建構函式
public myProcessViewModel()
{
    KillProcessItemCommand = new RelayCommand<ListBoxItem>(KillProcessItemExecute);
}

這裡使用ContextMenu.PlacementTarget來解決定位問題

官方文件:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.controls.contextmenu.placementtarget?view=windowsdesktop-6.0

簡單來說ContextMenu.PlacementTarget就是召出它的元素

預期是將該listboxitem當作引數傳入

使用如下命令即可

CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}"

(因為我將ContextMenu繫結在了listboxitem上 所以path直接指向PlacementTarget即可

如果將ContextMenu繫結在listbox上 可以令path指向PlacementTarget.SelectedItem