代码之家  ›  专栏  ›  技术社区  ›  Brad Leach

WPF-将鼠标悬停在一个元素上可显示另一个元素中的内容

wpf
  •  3
  • Brad Leach  · 技术社区  · 16 年前

    我想实现一种效果,我可以将鼠标悬停在按钮上,让文本块更新其内容(通过绑定)。更复杂的是,按钮是Items控件/数据模板中定义的许多按钮之一。TextBlock不在Items Control的作用域内。

    问题的一些简化标记如下:

    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>
      <ItemsControl Grid.Row="0">
        <ItemsControl.ItemTemplate>
          <DataTemplate>
            <Button Content="{Binding Title}"
                    Command="{Binding Command}" />    
          </DataTemplate>
        </ItemsControl.ItemTemplate>
      </ItemsControl>
      <TextBlock x:Name="TitleTextBox" Grid.Row="1" />
    </Grid>
    

    在这个例子中,我可能想将数据项的“Title”属性绑定到TextBlock的“Text”属性。

    我想我想点击按钮的IsMouseOver,但我似乎无法正确连接。

    1 回复  |  直到 16 年前
        1
  •  4
  •   wekempf    16 年前

    我不相信没有代码你就能完成这项工作。..但是,您不需要在后面使用代码。一种“行为”对此很有效(要么是老派 attached behavior ,或更现代的 Blend Behavior ).以下是使用附加行为修改后的标记的样子:

    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>
      <ItemsControl x:Name="Buttons" Grid.Row="0" ext:Hover.TrackChildItems="true">
        <ItemsControl.ItemTemplate>
          <DataTemplate>
            <Button Content="{Binding Title}"
                    Command="{Binding Command}" />
          </DataTemplate>
        </ItemsControl.ItemTemplate>
      </ItemsControl>
      <TextBlock x:Name="TitleTextBox"
                 Grid.Row="1"
                 Text="{Binding ElementName=Buttons, Path=ext:Hover.Item.Content}" />
    </Grid>
    

    这里,附加的行为“Hover.TrackChildItems”用于监视相应的鼠标事件,并将只读的“Hover.Item”附加属性设置为悬停在其上的控件。写行为应该足够简单,留给你。

    Mouse.AddMouseEnter(item, OnMouseEnter);
    

    这对于静态内容很好,但动态(在运行时添加和删除)内容将被忽略。因此,接下来您必须跟踪Items属性的更改。

    ((INotifyCollectionChanged)Items).CollectionChanged += OnItemsChanged;
    

    在CollectionChanged处理程序中添加和删除项目时,根据需要添加或删除鼠标事件处理程序。

    还有另一种解决方案。为此创建一个新的HoverTrackingItems控件,该控件派生自Items控件。在此控件中,重写GetContainerForItemOverride方法以返回一个新的HoverTrackingItem,该方法处理MouseEnter/MouseLeave以通知父级HoverTracking_Items控件。此解决方案可能更容易实现,尽管它确实需要专门的控件,而行为解决方案更通用,可以与任何Items control类型(Items control、列表框、组合框等)一起使用。