在我遇到的一个问题上,我一直在摸不着头脑,最终将其追溯到一个问题,将contextmenu作为静态资源。
我遇到的问题是,当我将contextmenu移动到一个静态资源中,并使用数据触发器根据一个对象的状态加载一个上下文菜单时,按钮命令似乎卡在了关联的datacontext上第一次加载,但另一个绑定工作正常。
我所拥有的是以下视图,其中包含使用自定义项目模板的列表视图,此项目模板为:
<DataTemplate x:Key="appListTemplate">
<Button cal:Message.Attach="Run" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#BBF7F7F7"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Height="50" HorizontalAlignment="Stretch" Background="{TemplateBinding Background}">
<Border CornerRadius="5" Height="35" Width="35" Background="SkyBlue" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="10,0,0,0"/>
<Label Content="{Binding AppName}" ToolTip="{Binding AppStatus}" VerticalAlignment="Center" Margin="50,0,0,0" FontSize="16"/>
<Image Source="{Binding Icon}" ToolTip="{Binding AppIconName}" Stretch="UniformToFill" Height="20" Width="20" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,15,0"/>
<StackPanel VerticalAlignment="Top">
<Line Stroke="#FFCDCDCD" Stretch="Fill" X2="1" />
<Line Stroke="#FFEAEAEA" Stretch="Fill" X2="1" />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding AppStatus}" Value="{x:Static enum:AppStatus.DISABLED}">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Background" Value="Lime"/>
</DataTrigger>
<DataTrigger Binding="{Binding AppStatus}" Value="{x:Static enum:AppStatus.NOACCESS}">
<Setter Property="Opacity" Value="0.5"/>
<Setter Property="ContextMenu" Value="{StaticResource ResourceKey=NoAccessContextMenu}" />
</DataTrigger>
<DataTrigger Binding="{Binding AppStatus}" Value="{x:Static enum:AppStatus.INSTALLED}">
<Setter Property="ContextMenu" Value="{StaticResource ResourceKey=InstalledContextMenu}"/>
</DataTrigger>
<DataTrigger Binding="{Binding AppStatus}" Value="{x:Static enum:AppStatus.NOTINSTALLED}">
<Setter Property="ContextMenu" Value="{StaticResource ResourceKey=UninstalledContextMenu}"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFF7F7F7"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
如您所见,根据状态,加载了不同的上下文菜单。这些被定义为:
<ContextMenu x:Key="InstalledContextMenu" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="RunApplication" Header="Run" cal:Message.Attach="Run"/>
<MenuItem Header="Uninstall" cal:Message.Attach="Uninstall"/>
</ContextMenu>
<ContextMenu x:Key="UninstalledContextMenu" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="Install" Header="Install" cal:Message.Attach="Install"/>
</ContextMenu>
<ContextMenu x:Key="NoAccessContextMenu" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="RequestAccess" Header="Request Access" cal:Message.Attach="RequestAccess"/>
</ContextMenu>
当您右键单击列表中的第一项时,会出现问题,它会正确显示选项E.G
SHIPPING
--------
Run
Uninstall
这项工作是100%,但是当您右键单击列表中的第二项时,您将获得以下内容:
PROJECTS
--------
Run
Uninstall
正如您所看到的,appname绑定更新正常,但是当您单击卸载时,它会调用运送VM上的卸载方法,它应该在项目VM上调用卸载。对于调用Shipping VM上的方法的每个项目,这将继续发生。
我完全失去了我能做些什么,甚至为什么会这样。任何帮助都是最受欢迎的。
答案 0 :(得分:0)
好的,感谢一些人的暗示,我最终追踪了这一点。 这个问题是由于上下文菜单不在可视化树中而引起的,并且微软提示&#34;修复&#34;是为了让contextmenu继承它的父级datacontext,但这只发生过一次,显然在更改datacontext时,例如更改listview中的选定项时,datacontext永远不会更新。
为了解决这个问题,我将contextmenu更改为以下内容。
<ContextMenu x:Key="InstalledContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="RunApplication" Header="Run" cal:Action.TargetWithoutContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}" cal:Message.Attach="Run"/>
<MenuItem Header="Uninstall" cal:Action.TargetWithoutContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}" cal:Message.Attach="Uninstall"/>
</ContextMenu>
<ContextMenu x:Key="UninstalledContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="Install" cal:Action.TargetWithoutContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}" Header="Install" cal:Message.Attach="Run"/>
</ContextMenu>
<ContextMenu x:Key="NoAccessContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" StaysOpen="False">
<MenuItem Header="{Binding AppName}" HorizontalContentAlignment="Right" FontWeight="Bold" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="RequestAccess" cal:Action.TargetWithoutContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}" Header="Request Access" cal:Message.Attach="RequestAccess"/>
</ContextMenu>
如您所见,我现在为datacontext创建自己的绑定,然后在每个菜单项上为我的校准微动作设置目标上下文。对于每个菜单项,这都需要做一些屁股,但似乎是最简单的修复。