Caliburn Micro 和 ContextMenu 导致找不到目标
Caliburn Micro and ContextMenu results in target not found
首先,我遇到这样的情况:
<components:ImageButton ImageSource="../Resources/Images/test.png" Height="32" Width="32" Style="{StaticResource MenuButtonWithContextMenuStyle}">
<components:ImageButton.ContextMenu>
<ContextMenu>
<MenuItem Header="Test" cal:Message.Attach="Test"/>
</ContextMenu>
</components:ImageButton.ContextMenu>
</components:ImageButton>
还有这种风格:
<Style TargetType="{x:Type components:ImageButton}" x:Key="MenuButtonWithContextMenuStyle">
<Setter Property="ToolTipService.IsEnabled" Value="False"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type components:ImageButton}">
<Grid x:Name="ContentGrid" Background="{TemplateBinding Background}" ToolTip="{TemplateBinding ToolTip}" ContextMenu="{TemplateBinding ContextMenu}">
<Image Source="{TemplateBinding ImageSource}" Height="12" Width="12" HorizontalAlignment="Center" IsEnabled="{TemplateBinding IsEnabled}" ToolTip="{TemplateBinding ToolTip}" Stretch="Uniform" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#22000000" TargetName="ContentGrid"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#33000000" TargetName="ContentGrid"/>
</MultiTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=ContentGrid, Path=ContextMenu.IsOpen}" Value="True"/>
<Condition Binding="{Binding ElementName=ContentGrid, Path=IsEnabled}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="#22000000" TargetName="ContentGrid"/>
</MultiDataTrigger>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.Target="{Binding ElementName=ContentGrid}" Storyboard.TargetProperty="ContextMenu.IsOpen" >
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
</Style.Triggers>
</Style>
一切都很基本,但我无法让 Caliburn 找到我的 'Test' 方法的目标。如果我将上下文菜单添加到样式 ( ) 而不是使用模板绑定,我可以让它工作,但这是一个我计划使用很多次的按钮,如果我不得不将其复制过来,我会讨厌它多次。
我已经在此处和 caliburn 站点上尝试了几个建议的修复方法(例如 TargetWithoutContext 方法),但它从未奏效。我不知道该如何解决这个问题。
ImageButton 是一个常规按钮,添加了 ImageSource 依赖项 属性。
好的,我要post回答我自己的问题。
你可以做的是使用这个:
BindingProxy (thanks to Daniel)
然后,这样使用:
cal:Action.Target="{Binding Source={StaticResource BindingProxy}, Path=Data}"
同样的问题存在于WindowsPhone7中,解决方法here。
基本上你想设置 cm:Action.TargetWithoutContext
使用 BindingProxy
作为另一个答案的建议或使用 ElementName
绑定。
首先,我遇到这样的情况:
<components:ImageButton ImageSource="../Resources/Images/test.png" Height="32" Width="32" Style="{StaticResource MenuButtonWithContextMenuStyle}">
<components:ImageButton.ContextMenu>
<ContextMenu>
<MenuItem Header="Test" cal:Message.Attach="Test"/>
</ContextMenu>
</components:ImageButton.ContextMenu>
</components:ImageButton>
还有这种风格:
<Style TargetType="{x:Type components:ImageButton}" x:Key="MenuButtonWithContextMenuStyle">
<Setter Property="ToolTipService.IsEnabled" Value="False"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type components:ImageButton}">
<Grid x:Name="ContentGrid" Background="{TemplateBinding Background}" ToolTip="{TemplateBinding ToolTip}" ContextMenu="{TemplateBinding ContextMenu}">
<Image Source="{TemplateBinding ImageSource}" Height="12" Width="12" HorizontalAlignment="Center" IsEnabled="{TemplateBinding IsEnabled}" ToolTip="{TemplateBinding ToolTip}" Stretch="Uniform" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#22000000" TargetName="ContentGrid"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#33000000" TargetName="ContentGrid"/>
</MultiTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=ContentGrid, Path=ContextMenu.IsOpen}" Value="True"/>
<Condition Binding="{Binding ElementName=ContentGrid, Path=IsEnabled}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="#22000000" TargetName="ContentGrid"/>
</MultiDataTrigger>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.Target="{Binding ElementName=ContentGrid}" Storyboard.TargetProperty="ContextMenu.IsOpen" >
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
</Style.Triggers>
</Style>
一切都很基本,但我无法让 Caliburn 找到我的 'Test' 方法的目标。如果我将上下文菜单添加到样式 ( ) 而不是使用模板绑定,我可以让它工作,但这是一个我计划使用很多次的按钮,如果我不得不将其复制过来,我会讨厌它多次。
我已经在此处和 caliburn 站点上尝试了几个建议的修复方法(例如 TargetWithoutContext 方法),但它从未奏效。我不知道该如何解决这个问题。
ImageButton 是一个常规按钮,添加了 ImageSource 依赖项 属性。
好的,我要post回答我自己的问题。
你可以做的是使用这个: BindingProxy (thanks to Daniel)
然后,这样使用:
cal:Action.Target="{Binding Source={StaticResource BindingProxy}, Path=Data}"
同样的问题存在于WindowsPhone7中,解决方法here。
基本上你想设置 cm:Action.TargetWithoutContext
使用 BindingProxy
作为另一个答案的建议或使用 ElementName
绑定。