【问题标题】:ZIndex for one canvas over an adjacent canvas一个画布在相邻画布上的 ZIndex
【发布时间】:2020-07-06 18:05:08
【问题描述】:

我正在尝试渲染一排互锁的箭头,如下所示:

每个箭头代表工作流程中的一个步骤,每个箭头的颜色取决于其步骤在工作流程中的位置。虽然上面的示例有 3 种颜色(之前、当前、之后),但到目前为止,我只实现了 2 种颜色(之前/当前、之后),这对于这个问题来说很好。我有一个IMultiValueConverter 来处理这些颜色。

工作流步骤表示为StepStruct,它有一个Step 属性(手动设置,稍后会详细介绍)和一个VmFunc 属性,它返回该步骤的视图模型。我当前的IMultiValueConverter 使用步骤列表中的步骤索引,而不是实际的Step 值。

我的问题是箭头。最初,我将每一步都作为画布呈现一个简单的矩形,这很容易上手。但是为了制作箭头,我使用了一个PolyLine,我想将它定位在画布的右侧,实际上是从一个画布的右侧开始并溢出到下一个画布。

我无法让Panel.ZIndex 以这样一种方式工作,即画布的箭头可见溢出到其右侧邻居中。

我的代码粘贴在下面。注意:

  • 我已经将PolylinePanel.Zindex(我读过它会影响其父画布的z-index)绑定到StepStructStep 属性,并且我已经设置了@987654337 @ 值,以便每个步骤的值小于其左侧步骤的值,这应该显示左侧步骤超过右侧步骤。
  • 我评论了一行设置每个PolyLineCanvas.Left 属性。当我取消注释这条线(并将其移动到位)时,Polyline 确实移到了画布的右侧,但它是不可见的,我想这是因为它隐藏在右侧的画布后面。 (我已经通过将 PolyLine 更改为以负 x 值开头来确认这一点,这样您就可以看到未被相邻画布阻挡的部分。这不是图片。)
  • 我已经将每个画布的Step 渲染为文本,而那些TextBlocks 都具有相同的z-index (40),因此它们位于一些PolyLines 的前面和其他的后面,这表明PolyLine 确实设置了正确的 z-index,至少在它自己的画布中。
<Border Grid.Row="0" BorderBrush="{StaticResource BackgroundBlack}" BorderThickness="2">

    <!--Progress bar-->
    <ItemsControl ItemsSource="{Binding StepViewModels}" Grid.Row="0" x:Name="progressBar">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="1"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas Height="24">
                    <Canvas.Style>
                        <Style TargetType="Canvas">
                            <Setter Property="Background" Value="{StaticResource BackgroundDarkGrey}"/>

                            <Style.Triggers>
                                <DataTrigger>
                                    <DataTrigger.Binding>
                                        <!-- the binding. this part works so I'm omitting the code -->
                                    </DataTrigger.Binding>
                                    <DataTrigger.Value>True</DataTrigger.Value>
                                    <Setter Property="Background" Value="{StaticResource DisabledGrey}"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Canvas.Style>

                    <Polyline Points="0,-1 20,11 0,25" Stroke="{StaticResource BackgroundBlack}" StrokeThickness="2" 
                            Fill="{Binding Background, RelativeSource={RelativeSource AncestorType=Canvas}}"
                            Panel.ZIndex="{Binding Step}"
                            />
                    <!--Canvas.Left="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Canvas}}"-->

                    <TextBlock Text="{Binding Step}" FontWeight="ExtraBlack" Panel.ZIndex="40" Foreground="Pink" FontSize="20" Canvas.Left="8"/>
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Border>

结果(Canvas.Left 仍被评论)

如何根据需要在一个画布的末端和下一个画布的顶部渲染箭头?

(我当然可以保持这种方式并使其工作,但是绑定会非常烦人和复杂,需要将每个箭头绑定到 previous 画布的颜色;或者更确切地说涉及IndexOf - 1的转换类型)

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    对于 ZIndex:

    每个项目都由一个 ContentPresenter 包装,这是由该 ItemsControl 实例中的 ItemContainerGenerator 完成的。

    因此您需要编辑容器以获取新的 ZIndex(例如通过 ContentPresenter 样式和绑定)。

    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Panel.ZIndex" Value="{Binding XXX}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    

    对于形状:

    我建议使用带有预定义几何形状的路径控件,例如:

    "M 0,0 L30,0 L34,5 L30,10 L0,10 z"

    并在末尾有一个负边距,例如 Margin="0,0,-4,0"

    【讨论】:

    • 谢谢。对负边际的好电话,我没想到。你能发布一个你提到的编辑容器的例子吗?
    • 在示例中编辑。
    • 谢谢,z-index 解决方案完美运行!我仍在使用以前的折线。为什么你更喜欢你建议的路径/边距解决方案?
    • 只是一种保持一致形状控制的方法,而不是一对组合。并不是说这很糟糕,只是如果您想为它们绘制相同的颜色以进行填充/描边,或者对它们进行一些操作,则更容易。
    猜你喜欢
    • 2011-06-28
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多