XAML 如何在ListBox控件之外以及在单击Item时在所有其他控件之上显示ListBox项

vcudknz3  于 2023-06-03  发布在  其他
关注(0)|答案(1)|浏览(237)

在我的解决方案中,我有一个ListBox控件,它动态地填充了项目,并且我的ListBox具有定义的高度和宽度。我有一个在ItemContainerStyle中定义的内容模板。当我点击每个项目时,我会在它们下面得到一个菜单,这就行了。但我面临的唯一问题是如何在列表框控件的最后一行显示菜单(实际上是最后一个被放置在底部的项目)而不切断菜单?因此,如果选择ListBox中的第一个项目,我的菜单将展开,如果选择最后一个项目,我的菜单将被切断。我想使用ZIndex,我设法访问它,但该项目不会显示定义的大小和ListBox控件之外。我可以提供代码,但有一个WPF ListBox控件,定义为ItemContainerStyle,其中我有切换按钮控件,最后在该切换按钮控件的样式中,我设置了一个ContentTemplate,其中有一个堆栈面板和我的菜单项(文本块和按钮)。你可以找到附加的图像,显示正是我想确认,ZIndex不工作,我不想滚动。我想说的是,我尝试了Preview Mouse Up Event handler,我可以找到它,因为我说,但设置ZIndex是不工作的。此外,我尝试与triggers的边界,这是一个面板周围我的菜单,但什么也没有。我期待着收到你的来信。

代码更新:
列表框控件

<ListBox x:Name="siteslist" MinWidth="505" MaxWidth="650" MaxHeight="205"
SelectedItem="{Binding DataContext.CurrentViewModel.SelectedMyValue, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
ItemsSource="{Binding DataContext.CurrentViewModel.MyValueView, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Style="{DynamicResource SiteListBoxStyle}"
ItemContainerStyle="{DynamicResource SiteListBoxItemStyle}"
ItemsPanel="{DynamicResource SiteItemsPanelTemplate}" PreviewMouseDown="Siteslist_OnPreviewMouseDown"
/>

ZINDEX事件-不工作

private void Siteslist_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
     var item = ItemsControl.ContainerFromElement(sender as ListBox, e.OriginalSource as DependencyObject) as ListBoxItem;
     if (item != null)
     {
        item.SetValue(Canvas.ZIndexProperty, 5);
     }
}

列表框项目的样式

<Style x:Key="SiteListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Padding" Value="0,0,0,0"/>
    <Setter Property="Margin" Value="0,34,0,0"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Background" Value="{DynamicResource TransparentBrush}"/>
    <Setter Property="BorderBrush" Value="{DynamicResource BorderTextBoxBrush}"/>
    <Setter Property="BorderThickness" Value="0,0,0,0"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
    <Setter Property="ContentTemplate" Value="{StaticResource ListBoxItemDataTemplate}"/>
    <Setter Property="Template">
          <Setter.Value>
              <ControlTemplate TargetType="{x:Type ListBoxItem}">
                 <Border x:Name="siteactions" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"
                      Height="{Binding Height, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}">
                    <ContentPresenter Content="{Binding}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                  </Border>
               <ControlTemplate.Triggers>
            <MultiTrigger>
                 <MultiTrigger.Conditions>
           <Condition Property="IsSelected" Value="True"/>
           <Condition Property="Selector.IsSelectionActive" Value="True"/>
                     </MultiTrigger.Conditions>
          <Setter Property="Panel.ZIndex" TargetName="siteactions" Value="100"/>
                    </MultiTrigger>
                 <MultiTrigger>
                 <MultiTrigger.Conditions>
                      <Condition Property="IsSelected" Value="True"/>
                      </MultiTrigger.Conditions>
                      <Setter Property="BorderBrush" TargetName="siteactions" Value="Blue"/>
                         <Setter Property="BorderThickness" TargetName="siteactions" Value="2"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

列表框项内容模板

<DataTemplate x:Key="ListBoxItemDataTemplate" DataType="{x:Type models:Site}">
                <ToggleButton x:Name="choosesite" IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" 
                             Content="{Binding MyValue}" Tag="{Binding Location}" 
                             Style="{DynamicResource SiteButtonStyle}"
                             Command="{Binding Path=DataContext.CurrentViewModel.ClickSiteCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                             CommandParameter="{Binding ElementName=choosesite, Path=IsChecked}"/>
    </DataTemplate>

切换按钮样式

<Style x:Key="SiteButtonStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource Button.Static.Border}"/>
        <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
        <Setter Property="Foreground" Value="{StaticResource Button.Static.Background}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Height" Value="Auto"/>
        <Setter Property="Template" Value="{StaticResource SiteButtonTemplate}"/>
        <Setter Property="ContentTemplate" Value="{StaticResource SiteDataTemplate}"/>
    </Style>

内容数据模板-我的菜单

<DataTemplate x:Key="SiteDataTemplate">
        <StackPanel x:Name="SiteActionsPanel" HorizontalAlignment="Center" VerticalAlignment="Top" > <!--Height="40"-->
            <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center" FontWeight="SemiBold"  
                       Text="{TemplateBinding Content}"/>
            <TextBlock x:Name="sitelocation" TextWrapping="Wrap" TextAlignment="Center" FontFamily="Roboto" FontSize="11" 
                       Foreground="{DynamicResource GrayButtonBrush}"
                       Text="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"/>
            <Border x:Name="SiteActionsBorder" >
                <StackPanel Margin="0,20,0,0" x:Name="SiteActions" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed">
                    <Grid HorizontalAlignment="Center" VerticalAlignment="Top">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Button x:Name="choose" HorizontalAlignment="Left" Height="40" Style="{DynamicResource ChooseButtonStyle}" Content="Choose" Grid.Row="0" Panel.ZIndex="99"
                            Command="{Binding Path=DataContext.CurrentViewModel.ChooseSiteCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                            CommandParameter="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                        <ToggleButton x:Name="delete" Width="70" Grid.Row="1" Panel.ZIndex="99"
                              IsChecked="{Binding DataContext.CurrentViewModel.IsDeleteConfirmed, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                              Style="{StaticResource DeleteConfirmToggleButtonStyle}"
                              Command="{Binding DataContext.CurrentViewModel.ConfirmDeleteSiteCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                              CommandParameter=""/>
                        <Button x:Name="edit" HorizontalAlignment="Left" Height="40" Style="{DynamicResource EditButtonStyle}" Content="Edit" Panel.ZIndex="99" Grid.Row="2"
                                    Command="{Binding Path=DataContext.CurrentViewModel.EditSiteCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                    CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
                    </Grid>
                </StackPanel>
            </Border>
        </StackPanel>
       <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=IsPressed, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
                <Setter Property="Foreground" TargetName="sitelocation" Value="{DynamicResource ChoosenButtonBrush}"/>
                <!--<Setter Property="Height" TargetName="SiteActionsPanel" Value="155"/>-->
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
                <Setter Property="Visibility" TargetName="SiteActions" Value="Visible"/>
                <Setter Property="Foreground" TargetName="sitelocation" Value="{DynamicResource ChoosenButtonBrush}"/>
                <!--<Setter Property="Height" TargetName="SiteActionsPanel" Value="155"/>-->
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=DataContext.CurrentViewModel.IsChoosenSite, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Value="True">
                <Setter Property="Visibility" TargetName="SiteActions" Value="Collapsed"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
gudnpqoy

gudnpqoy1#

您可以使用ContextMenu来托管您的菜单。因为ContextMenu在默认情况下是在右键单击时打开的,所以你必须在左键单击时手动打开它(或者ListBoxItem.Selected或任何你想要的自定义触发器)。
Popup相比,ContextMenu的优势在于ContextMenu已经实现了通常的对焦行为。此外,菜单项看起来像普通的上下文菜单项,无需进一步的配置和布局修改。

MainWindow.xaml

<Style TargetType="ListBoxItem">
  <EventSetter Event="MouseLeftButtonUp"
               Handler="ListBoxItem_MouseLeftButtonUp" />
  <Setter Property="ContextMenu">
    <Setter.Value>
      <ContextMenu>
        <MenuItem Header="Menu Item #1" Click="Click event handler" />
        <MenuItem Header="Menu Item #2" Command="Alternative command handler" />
        <MenuItem Header="Menu Item #3" />
      </ContextMenu>
    </Setter.Value>
  </Setter>
</Style>

MainWindow.xaml.cs

private void ListBoxItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
  var listBoxItem = sender as ListBoxItem;
  listBoxItem.ContextMenu.IsOpen = true;
}

相关问题