1

TreeView ContextMenu 未触发事件(ContextMenu Opened 事件未触发),我正在尝试 Caliburn.Micro.Telerik 约定未解决问题。

树视图项目模板

    <HierarchicalDataTemplate x:Key="TreeViewItemTemplate" ItemsSource="{Binding Types}"
    ItemTemplateSelector="{StaticResource NamespaceItemTemplateSelector}">
<StackPanel Orientation="Horizontal">
    <Path
            Data=""
            Height="11.458" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5" Stretch="Fill"
            UseLayoutRounding="False" Width="11.264">
        <Path.Fill>
            <SolidColorBrush Color="#FF333333">
                <SolidColorBrush.RelativeTransform>
                    <MatrixTransform Matrix="Identity" />
                </SolidColorBrush.RelativeTransform>
                <SolidColorBrush.Transform>
                    <MatrixTransform Matrix="Identity" />
                </SolidColorBrush.Transform>
            </SolidColorBrush>
        </Path.Fill>
        <Path.RenderTransform>
            <TransformGroup>
                <ScaleTransform />
                <SkewTransform />
                <RotateTransform />
                <TranslateTransform />
            </TransformGroup>
        </Path.RenderTransform>
    </Path>
    <TextBlock Text="{Binding Header}" Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}">
   <TextBlock.ContextMenu>
 <ContextMenu cal:Action.TargetWithoutContext="{Binding RelativeSource={RelativeSource Self},Path=UIElement.Tag}" cal:Message.Attach="[Event Opened] = [Action Opened($dataContext)]" >
       <MenuItem Header="NewChild" cal:Message.Attach="NewChild($datacontext)"/>
         </ContextMenu>
  </TextBlock.ContextMenu>
    </TextBlock>
</StackPanel>

树视图

<TreeView x:Name="TreeView" ItemTemplate="{StaticResource TreeViewItemTemplate}" ItemsSource="{Binding Source}"/>
4

1 回答 1

4

在我告诉你问题是什么之前,我想指出你上传的代码版本与你在问题中发布的版本有点不同。

好的,问题恰好出在模板的这一部分:

<TextBlock Text="{Binding Header}" Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}">
    <TextBlock.ContextMenu>
        <ContextMenu cal:Action.TargetWithoutContext="{Binding RelativeSource={RelativeSource Self},Path=UIElement.Tag}" cal:Message.Attach="[Event Opened] = [Action Opened($dataContext)]" >
            <MenuItem Header="NewChild" cal:Message.Attach="NewChild($datacontext)"/>
        </ContextMenu>
    </TextBlock.ContextMenu>
</TextBlock>

要修复它,您需要用这个修改后的版本替换它:

<TextBlock Text="{Binding Header}" Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}">
    <TextBlock.ContextMenu>
        <ContextMenu cal:Action.TargetWithoutContext="{Binding RelativeSource={RelativeSource Self},Path=PlacementTarget.Tag}" cal:Message.Attach="[Event Opened] = [Action ContextMenuOpened($source)]">
            <MenuItem Header="New" cal:Message.Attach="[Event Click] = [Action ClickMenuItem($source)]"/>
        </ContextMenu>
    </TextBlock.ContextMenu>
</TextBlock>

问题是由三个问题引起的:

  1. 在模板中,特别是在这行代码<ContextMenu cal:Action.TargetWithoutContext="{Binding RelativeSource={RelativeSource Self},Path=UIElement.Tag}"中,导致绑定错误,因为调用Path=UIElement.Tag的类型上没有属性。相反,您必须将其替换为表示打开上下文菜单的用户界面中的元素的属性。ContextMenuUIElementPlacementTarget
  2. 第二个问题是您将处理这些事件的方法放在了错误的类上。它们不应该在 .ShellViewModel因为在模板中您将 设置Action.Target为实际上是DataContext在您的情况下,所以方法应该在.TextBlockNamespaceViewModelNamespaceViewModel
  3. 第三个也是最后一个问题是您的方法具有错误的签名,因此 Caliburn.Micro 无法找到它们。我的意思是您正在这样声明您的ContextMenuOpened方法:void ContextMenuOpened(sender args, RoutedEventArgs args);但是在模板中您正在调用这样的方法:[Action ContextMenuOpened($source)]它发送FrameworkElement导致事件的方法ContextMenu在这种情况下),因此您应该更改此事件的方法签名对此:void ContextMenuOpened(ContextMenu source)或更一般的void ContextMenuOpened(FrameworkElement source)

概括:

  1. 修复您的模板以使用该PlacementTarget属性。
  2. 将您的方法移至NamespaceViewModel.
  3. 修复您的方法签名。

最后:如果您想了解有关操作和操作消息的所有信息以及将哪些参数传递给什么,那么您应该真正阅读有关Actions的文档 wiki 。

于 2013-07-18T10:19:04.927 回答