gpt4 book ai didi

wpf - ContextMenu.PlacementTarget 未设置,不知道为什么

转载 作者:行者123 更新时间:2023-12-04 18:52:01 25 4
gpt4 key购买 nike

<DataTemplate x:Key="_ItemTemplateA">
<Grid Tag="{Binding Path=DataContext.Command, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource ContentTemplateB}" Grid.Row="0" />
<ContentControl Name="uiContentPresenter" Content="{Binding ContentView}" Grid.Row="1" Height="0" />
<ContentControl DataContext="{Binding IsContentDisplayed}" DataContextChanged="IsDisplayed_Changed" Visibility="Collapsed" />
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Text"
Command="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
CommandParameter="{Binding}" />
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</DataTemplate>

上述数据模板应用于 ItemsControl。问题是,对于为 Grid 指定的 ContextMenu,PlacementTarget 属性实际上从未设置为任何内容,因此我无法访问 Grid 的 Tag 属性,这是传递应该在父 UserControl 上执行的命令所必需的到上下文菜单。这种方法基于类似的示例,例如: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0244fbb0-fd5f-4a03-bd7b-978d7cbe1be3/

我无法确定传递此命令的任何其他好方法。这是这样设置的,因为我们使用的是 MVVM 方法,因此我们必须执行的命令存在于应用此模板的用户控件的 View 模型中。我尝试以几种不同的方式显式设置 PlacementTarget 但它仍然总是显示为未设置。

最佳答案

我意识到这是旧的并且已回答,但似乎没有正确回答。我遇到了一个 similar post并留下了完整的答案。您可能想看一下,只需对代码进行一些调整即可使其正常工作。

首先,为您的 View 命名 UserControl ...我通常将我的全部命名为 This为简单起见。然后记住我们的 View 模型绑定(bind)到 DataContextUserControl ,我们可以使用 {Binding DataContext, ElementName=This} 绑定(bind)到 View 模型.

所以现在我们可以绑定(bind)到 View 模型,我们必须将它与 ContextMenu.DataContext 连接起来。 .我使用 Tag ContextMenu 的对象的属性( PlacementTarget )作为该连接,在本例中为 Grid :

<DataTemplate x:Key="YourTemplate" DataType="{x:Type DataTypes:YourDataType}">
<Grid ContextMenu="{StaticResource Menu}" Tag="{Binding DataContext,
ElementName=This}">
...
</Grid>
</DataTemplate>

然后我们可以访问 ContextMenu 中的 View 模型属性和命令。通过绑定(bind) ContextMenu.DataContext PlacementTarget.Tag 的属性(property)属性(在我们的示例中属于 Grid):
<ContextMenu x:Key="Menu" DataContext="{Binding PlacementTarget.Tag, RelativeSource=
{RelativeSource Self}}">
<MenuItem Header="Delete" Command="{Binding DeleteFile}" CommandParameter=
"{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource
AncestorType=ContextMenu}}" CommandTarget="{Binding PlacementTarget,
RelativeSource={RelativeSource Self}}" />
</ContextMenu>

注意 MenuItem.CommandTarget 上的绑定(bind)属性(property)。设置此项可确保引发指定命令的目标元素是 PlacementTarget ,或 Grid在这种情况下。

另请注意 CommandParameter捆绑。这绑定(bind)到 DataContextPlacementTarget ,或 Grid在这种情况下。 DataContextGrid将从 DataTemplate 继承所以你的数据项现在绑定(bind)到 object Command 中的参数如果您正在使用 ICommand 的某些实现界面:
public bool CanExecuteDeleteFileCommand(object parameter)
{
return ((YourDataType)parameter).IsInvalid;
}

public void ExecuteDeleteFileCommand(object parameter)
{
Delete((YourDataType)parameter);
}

或者,如果您使用某种 RelayCommand直接在您的 View 模型中委托(delegate):
public ICommand Remove
{
get
{
return new ActionCommand(execute => Delete((YourDataType)execute),
canExecute => return ((YourDataType)canExecute).IsInvalid);
}
}

关于wpf - ContextMenu.PlacementTarget 未设置,不知道为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4739282/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com