Caliburn中的ContextMenu.Closed事件未触发动作

时间:2014-02-24 11:46:27

标签: wpf caliburn.micro

我正在使用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的关闭事件中,视觉树会以某种方式发生变化,这意味着不再找到该方法,但是有没有可能的解决方法呢?

1 个答案:

答案 0 :(得分:0)

这有多典型?花了两天时间回到这个问题,我在这里发布,然后5分钟后发现它...

关键是改为:

<Grid HorizontalAlignment="Center" Tag="{Binding DataContext, ElementName=IndividualQueue}" cal:Message.Attach="[Event ContextMenuClosing] = [Action ResumeUpdates()]">

从Grid中捕获结束事件而不是ContextMenu本身。