【问题标题】:Setting zindex for rectangle on canvas is not bringing it to front在画布上为矩形设置 zindex 不会将其置于前面
【发布时间】:2013-01-23 20:44:39
【问题描述】:

我遇到了画布和画在上面的矩形的问题。 他们以相反的创建顺序获取事件(最新的在顶部),而不是 zindex 的顺序......

我已将 ItemsControl 与资源列表绑定。

然后有一个画布作为项目面板:

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Canvas x:Name="BitmapCanvas"/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

所有资源都绑定为矩形:

<ItemsControl.ItemTemplate>
    <DataTemplate DataType="interfaces:IResourceView">
        <Rectangle ...>

还有一种风格:

<Rectangle.Style>
    <Style TargetType="{x:Type Rectangle}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="true">
                <Setter Property="Canvas.ZIndex" Value="0"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="false">
                <Setter Property="Canvas.ZIndex" Value="15"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    ...</Rectangle.Style></Rectangle></DataTemplate></ItemsControl.ItemTemplate>

正如你所看到的,当矩形被选中时,我将它的 Zindex 设置为 0,然后其他的 zindex 值更大。我也在尝试交换值,但仍然 矩形也以同样的方式获得焦点。 有人知道为什么会这样吗?

【问题讨论】:

  • 不确定这是否相关,但我想知道为什么您的 Style 位于 Rectangle.Style 而不是 ItemsControl.Resources 或树上方的其他资源标签中。
  • 这是我自己的类 Rectangle,它实现了 INotifyPropertyChanged。这个问题中最好的一点是这个 ZIndex 设置正确。我在引发 MouseMove 事件时记录它。
  • 哦,我明白你现在在做什么了。
  • 绑定的 IsSelected 属性来自 IResourceView。矩形来自 windows.shapes 我自己的带有 INotifyPropertyChanged 的​​ Rectangle 类在 IResourceView 中是“隐藏的”;)所有样式都在工作,在检查“真”值的数据触发器上还有其他设置器,它们也正常工作......跨度>
  • 我确定您已经这样做了,但是您是否验证过您在设置 IsSelected 属性时触发 NotifyPropertyChanged(假设 IsSelected 在您的自定义 Rectangle 中定义。即If (PropertyChanged!=null) PropertyChanged(this, new PropertyChangedEventArgs("IsSelected");

标签: c# wpf canvas z-index


【解决方案1】:

在 DataTemplate 中的 Rectangle 上设置 Canvas.ZIndex(或实际上是 WPF 中的 Panel.ZIndex)无效,因为这些 Rectangle 不是 ItemsPanelTemplate 中 Canvas 的直接子级。换句话说,Rectangles 没有兄弟姐妹,但ZIndex 是一个相对值,只影响同一个容器控件的兄弟姐妹。

实际上每个矩形都被放入 ContentPresenter 的 Content 中(它是 ItemsControl 的项目容器类型)。然后将这些 ContentPresenter 放入 Canvas。

为了使事情正常进行,您可以将 DataTriggers 移动到 ItemContainerStyle

<ItemsControl.ItemContainerStyle>
    <Style TargetType="ContentPresenter">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="true">
                <Setter Property="Panel.ZIndex" Value="0"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="false">
                <Setter Property="Panel.ZIndex" Value="15"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ItemsControl.ItemContainerStyle>

【讨论】:

  • 但是,您的 ZIndex 值表明所选项目应位于其他项目之后,因为 0 低于 15。
【解决方案2】:

您的问题在于您的触发器。 Style 仅支持 EventTrigger,不支持任何其他类型,因此您的触发器将永远不会被执行。不过,您在 DataTemplate 中,并且它们确实支持 DataTrigger,因此您可以移动一些东西来解决问题:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Rectangle x:Name="Rect"/>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="true">
                <Setter TargetName="Rect" Property="Canvas.ZIndex" Value="0"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsSelected}" Value="false">
                <Setter TargetName="Rect" Property="Canvas.ZIndex" Value="15"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ItemsControl.ItemTemplate>

【讨论】:

  • ZIndex 如果在 Rectangle 上设置仍然无效。它必须在 ContentPresenter 上设置。
  • 而且 DataTrigger 仍然无法在 Style 中工作,无论您设置什么类型。
  • @JohnBowen "样式仅支持 EventTrigger"。你从哪里得到的?也许是一些旧的 WPF 版本?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多