我正在使用Caliburn在WPF中开发一个小应用程序,虽然大多数情况下都是一种喜悦,但有一个例外。 ContextMenus。在SO和其他地方经过大量搜索,学习和阅读这个主题后,我意识到在WPF和Caliburn中,ContextMenus或多或少都被打破了,但我无法在这个项目中避免它们。
我的问题是,对于许多其他人来说,似乎是范围和视觉树的问题,但它有点不同。我终于让ContextMenus正确地冒泡除了“ContextMenu.Closed”事件之外的动作。我的代码:
查看:
<UserControl x:Class="WPFClient.Plugins.IndividualDataView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
x:Name="IndividualQueue">
<ItemsControl x:Name="Channels">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center" Tag="{Binding DataContext, ElementName=IndividualQueue}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ContextMenu>
<ContextMenu Name="individualcm"
cal:Message.Attach="[Event Opened] = [Action FreezeUpdates()];[Event Closed] = [Action ResumeUpdates()]"
cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="{Binding Initials}" cal:Message.Attach="[Event Click] = [Action SetInactive()]" />
</ContextMenu>
</Grid.ContextMenu>
<Image Height="24" Width="24" Margin="3, 3, 3, 3" HorizontalAlignment="Left" Source="{Binding urlImage}" Grid.Row="0" />
<TextBlock Name="Initials" Text="{Binding Initials}" Grid.Row="1" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
视图模型:
public void FreezeUpdates()
{
_events.Unsubscribe(this);
}
public void ResumeUpdates()
{
_events.Subscribe(this);
}
关键是为了避免ItemsControl在ContextMenu因为传入事件而打开时更新(如果有更多用户/频道登录会破坏MenuItem)我想在菜单打开时取消订阅事件然后重新订阅。但是,虽然FreezeUpdates()在上面的示例中运行完美,但ResumeUpdates由于某种原因给出了“找不到方法ResumeUpdates的目标”。异常。
我想问题是,在ContextMenu的关闭事件中,视觉树会以某种方式发生变化,这意味着不再找到该方法,但是有没有可能的解决方法呢?
答案 0 :(得分:0)
这有多典型?花了两天时间回到这个问题,我在这里发布,然后5分钟后发现它...
关键是改为:
<Grid HorizontalAlignment="Center" Tag="{Binding DataContext, ElementName=IndividualQueue}" cal:Message.Attach="[Event ContextMenuClosing] = [Action ResumeUpdates()]">
从Grid中捕获结束事件而不是ContextMenu本身。