C# 在DataTemplate的ContextMenu中绑定根项属性

C# 在DataTemplate的ContextMenu中绑定根项属性,c#,wpf,data-binding,contextmenu,C#,Wpf,Data Binding,Contextmenu,问题似乎在于ContextMenu在设计上是一个孤儿,没有可视或逻辑父元素,我尝试使用PlacementTarget设置DataContext,但没有成功 <DataTemplate x:Key="ODIF.Device"> <Button HorizontalContentAlignment="Stretch" Background="WhiteSmoke" Padding="10,1" ContextMenuService.Placement="Right"

问题似乎在于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:找不到与绑定的源 参考'ElementName=page'。 BindingExpression:Path=OutputDeviceInputChannelsVisible; DataItem=null;目标元素是“ContextMenu”(名称=“”);目标 属性为“NoTarget”(类型为“Object”)

这是由于ElementName无法从上下文菜单爬升逻辑树或可视树

我接近86'的上下文菜单,并重新设计它使用一个正常的菜单,但我想我会给这样一个裂缝在第一次

根据下面的评论修改。这几乎可以正常工作,但是遵循此格式的条件绑定不起作用,需要它们来检查绑定数据的按钮

    <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>