问题似乎在于ContextMenu是一个孤立的孩子,并且没有视觉或逻辑父元素,我尝试使用PlacementTarget设置DataContext但没有运气。
<DataTemplate x:Key="ODIF.Device">
<Button HorizontalContentAlignment="Stretch" Background="WhiteSmoke" Padding="10,1" ContextMenuService.Placement="Right" VerticalContentAlignment="Stretch" Tag="{Binding ElementName=page}">
<Button.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC9C9C9" Offset="1"/>
<GradientStop Color="WhiteSmoke" Offset="0"/>
</LinearGradientBrush>
</Button.BorderBrush>
<i:Interaction.Behaviors>
<local:DropDownButtonBehavior/>
</i:Interaction.Behaviors>
<Button.ContextMenu>
<ContextMenu ItemTemplate="{StaticResource ODIF.Channel}" DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget}">
<ContextMenu.Style>
<Style TargetType="ContextMenu">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:InputDevice}" />-->
<Condition Binding="{Binding inputDevicesInputChannelsVisible, ElementName=page}" Value="True" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible, ElementName=page}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="InputChannels"/>
<Binding Path="OutputChannels"/>
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:InputDevice}" />-->
<Condition Binding="{Binding inputDevicesInputChannelsVisible, ElementName=page}" Value="False" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible, ElementName=page}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="OutputChannels"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:InputDevice}" />-->
<Condition Binding="{Binding inputDevicesInputChannelsVisible, ElementName=page}" Value="True" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible, ElementName=page}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="InputChannels"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:OutputDevice}" />-->
<Condition Binding="{Binding outputDevicesInputChannelsVisible, ElementName=page}" Value="True" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible, ElementName=page}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="InputChannels"/>
<Binding Path="OutputChannels"/>
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:OutputDevice}" />-->
<Condition Binding="{Binding outputDevicesInputChannelsVisible, ElementName=page}" Value="False" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible, ElementName=page}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="OutputChannels"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!--<Condition Binding="{Binding Converter={StaticResource TypeOfConverter}}" Value="{x:Type ODIF:OutputDevice}" />-->
<Condition Binding="{Binding outputDevicesInputChannelsVisible, ElementName=page}" Value="True" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible, ElementName=page}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="InputChannels"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ContextMenu.Style>
<!--<ContextMenu.ItemsSource>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="InputChannels"/>
<Binding Path="OutputChannels"/>
</MultiBinding>
</ContextMenu.ItemsSource>-->
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource NoIconColumnMenuItem}">
</Setter>
<EventSetter Event="Click" Handler="ChannelClick"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Button.ContextMenu>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Width="32" Height="32" Source="{Binding StatusIcon}" Grid.RowSpan="2" RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Grid.Column="1" Text="{Binding DeviceName}" FontWeight="Bold" FontSize="13.333" Foreground="#FF0F0970"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding}"/>
<Button Grid.Column="2" Content="X" Visibility="{Binding isImplicitlyRemoveable, Converter={StaticResource BoolToVisibilityConverter}}" Click="RemoveDevice" HorizontalAlignment="Right" VerticalAlignment="Top" Background="#FFF08F8F" BorderBrush="#FFBD4848" Foreground="White" FontWeight="Bold" Padding="2,0"/>
</Grid>
</Button>
</DataTemplate>
错误很明显:
System.Windows.Data错误:4:找不到绑定源 参考&#39; ElementName = page&#39;。 BindingExpression:路径= outputDevicesInputChannelsVisible; 的DataItem = NULL;目标元素是&#39; ContextMenu&#39; (名称=&#39;&#39);目标 物业是NoCarget&#39; (键入&#39;对象&#39;)
这是因为ElementName无法从上下文菜单中爬行逻辑树或可视树。
我接近上下文菜单并重新设计它以使用普通菜单,但我想先给它一个裂缝。
根据以下评论修改。这几乎正常,但是遵循此格式<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:OutputDevice}" />
的条件绑定不起作用,需要检查按钮绑定数据
<DataTemplate x:Key="ODIF.Device">
<Button HorizontalContentAlignment="Stretch" Background="WhiteSmoke" Padding="10,1" ContextMenuService.Placement="Right" VerticalContentAlignment="Stretch" Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page}}}">
<Button.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC9C9C9" Offset="1"/>
<GradientStop Color="WhiteSmoke" Offset="0"/>
</LinearGradientBrush>
</Button.BorderBrush>
<i:Interaction.Behaviors>
<local:DropDownButtonBehavior/>
</i:Interaction.Behaviors>
<Button.ContextMenu>
<ContextMenu ItemTemplate="{StaticResource ODIF.Channel}" DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<ContextMenu.Style>
<Style TargetType="ContextMenu">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:InputDevice}" />
<Condition Binding="{Binding inputDevicesInputChannelsVisible}" Value="True" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="DataContext.InputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
<Binding Path="DataContext.OutputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:InputDevice}" />
<Condition Binding="{Binding inputDevicesInputChannelsVisible}" Value="False" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="DataContext.OutputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:InputDevice}" />
<Condition Binding="{Binding inputDevicesInputChannelsVisible}" Value="True" />
<Condition Binding="{Binding inputDevicesOutputChannelsVisible}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="DataContext.InputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:OutputDevice}" />
<Condition Binding="{Binding outputDevicesInputChannelsVisible}" Value="True" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="DataContext.InputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
<Binding Path="DataContext.OutputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:OutputDevice}" />
<Condition Binding="{Binding outputDevicesInputChannelsVisible}" Value="False" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="DataContext.OutputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=DataContext,Converter={StaticResource TypeOfConverter},RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="{x:Type ODIF:OutputDevice}" />
<Condition Binding="{Binding outputDevicesInputChannelsVisible}" Value="True" />
<Condition Binding="{Binding outputDevicesOutputChannelsVisible}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="ItemsSource">
<Setter.Value>
<Binding Path="DataContext.InputChannels" RelativeSource="{RelativeSource AncestorType={x:Type Button}}"/>
</Setter.Value>
</Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ContextMenu.Style>
<!--<ContextMenu.ItemsSource>
<MultiBinding>
<MultiBinding.Converter>
<local:CompositeCollectionConverter/>
</MultiBinding.Converter>
<Binding Path="InputChannels"/>
<Binding Path="OutputChannels"/>
</MultiBinding>
</ContextMenu.ItemsSource>-->
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource NoIconColumnMenuItem}">
</Setter>
<EventSetter Event="Click" Handler="ChannelClick"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Button.ContextMenu>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Width="32" Height="32" Source="{Binding StatusIcon}" Grid.RowSpan="2" RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Grid.Column="1" Text="{Binding DeviceName}" FontWeight="Bold" FontSize="13.333" Foreground="#FF0F0970"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding}"/>
<Button Grid.Column="2" Content="X" Visibility="{Binding isImplicitlyRemoveable, Converter={StaticResource BoolToVisibilityConverter}}" Click="RemoveDevice" HorizontalAlignment="Right" VerticalAlignment="Top" Background="#FFF08F8F" BorderBrush="#FFBD4848" Foreground="White" FontWeight="Bold" Padding="2,0"/>
</Grid>
</Button>
</DataTemplate>