【问题标题】:WPF Listbox items with name on mouseover or active鼠标悬停或活动名称的 WPF 列表框项目
【发布时间】:2016-09-07 22:31:39
【问题描述】:

我已经尝试了几种不同的解决方案,但无法找到满足我所有需求的解决方案。

我们有一个可观察的对象集合,每个对象都有一个状态和一个名称。这是一种运行项目的任务列表。为了在 WPF 中显示这个列表,我们有一些代码将每个项目表示为带有一些颜色和动画的椭圆。

问题是我们希望在鼠标悬停或任务处于给定状态时将项目名称显示为“弹出窗口”。


尝试 #1

我第一次尝试将其实现为带有实际 WPF 弹出窗口的数据模板(用作 ItemTemplate)。我实现了两个数据触发器——一个用于鼠标悬停,一个用于任务状态。我根据我的椭圆定位弹出窗口,一切都很棒。但是,移动窗口或切换到其他窗口会使弹出窗口位于所有内容之上。


尝试 #2

我没有使用弹出窗口,而是在画布中使用了一个文本框。在列表框中使用数据模板之前,这非常有效。项目主机(堆栈面板)最终会剪切字符串。

下面是示例代码:

<DataTemplate x:Key="EllipseTemplate">
    <Grid Height="40" Width="40">
        <Canvas Name="PopupCanvas" HorizontalAlignment="Center" Width="500">
            <TextBlock Name="PopupName"
                   Width="{Binding ElementName=PopupCanvas, Path=ActualWidth}"
                   Text="{Binding}"
                   Background="Transparent"
                   FontSize="16" HorizontalAlignment="Center" TextAlignment="Center" FontWeight="Bold" 
                   Canvas.Top="-25"
                   Visibility="Collapsed"
                   />
        </Canvas>
        <Ellipse x:Name="Ellipse" Height="25" Width="25" Margin="0"
                 HorizontalAlignment="Center" VerticalAlignment="Center"
                 Fill="Green" 
                 RenderTransformOrigin="0.5, 0.5" StrokeThickness="0.5" Stroke="Black">
        </Ellipse>
    </Grid>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
            <Setter TargetName="PopupName" Property="Visibility" Value="Visible" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

<Grid Name="Test" Background="LightGoldenrodYellow" ClipToBounds="False" Margin="50">
    <ListBox Name="OverlayTest" 
             Background="CornflowerBlue" 
             BorderThickness="0" 
             VerticalAlignment="Center" 
             Margin="10" 
             ClipToBounds="False" 
             ItemTemplate="{StaticResource EllipseTemplate}">
        <sys:String>Very long string that will get clipped</sys:String>
        <sys:String>Two</sys:String>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" IsItemsHost="True" Margin="10,50,10,50" ClipToBounds="False"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>


尝试 #3

我将我的画布/文本框移到了数据模板之外,并创建了一个网格将其放在省略号列表框的上方。这从布局的角度来看是可行的,但是在检查鼠标悬停和将文本框置于活动/悬停的控件上时会造成很大的混乱。


所以这让我没有按我想要的方式工作的实现。有人有什么建议吗?

【问题讨论】:

    标签: c# wpf xaml listbox


    【解决方案1】:

    好的,我有另一个想法。我之前遇到过ListBox 的问题。尝试将ListBox 替换为ItemsControl

    【讨论】:

      【解决方案2】:

      尝试 #2 听起来工作正常。您应该能够使用以下解决方案之一(或全部)解决剪辑问题:

      1. ListBoxClipToBounds 属性设置为false
      2. StackpanelClipToBounds 属性设置为false

      【讨论】:

      • 是的,您认为这会起作用,但事实并非如此。我尝试在所有内容上添加 ClipToBounds=False,但没有帮助。
      • 在您在数据模板中发布 Grid 的 XAML 和名为 PopupCanvasCanvas 中没有设置 ClipToBounds 属性。我也知道这与问题无关,但我只是注意到TextBoxVisibility = Collapsed。我会尝试的另一件事是不使用Canvas 来放置TextBox,而是使用GridColumDefinitionsRowDefinition 来排列模板。
      • 我认为问题可能出在Grid 和/或CanvasClipToBound 属性上,因为您将Width 修复为Grid。试试看。这个问题可能是因为文本太大,无法放入 GridWidth 40 中,所以被剪裁了。
      • 将 ClipToBounds=false 添加到画布和网格中,没有任何变化。还更改了 TextBlock 的可见性,但没有任何效果。值得注意的是,用作内容控件的 EllipseTemplate 按预期工作,没有剪辑(即使与其他 EllipseTemplate 一起排列在堆栈面板中)。只有在与列表框结合使用时才会发生剪辑。
      • 好的,我有另一个想法。我之前遇到过ListBox 的问题。尝试将ListBox 替换为ItemsControl
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多