在触发器中设置父索引的Z索引

时间:2012-03-08 09:38:00

标签: c# wpf xaml triggers wpf-controls

我有一个ItemsControl,它有一个Canvas,因为它是ItemsPanel,项目是简单的边框,边框的细节是从视图模型数据绑定,数据如X,Y宽度,高度,颜色等我很快意识到甚至虽然我可以将大小和颜色等大多数数据绑定到边框项本身,但我必须在ItemsControl容器样式中绑定点数据和ZIndex,我相信这是因为这些属性仅适用于作为ContentPresenter的ItemContainer:

<ItemsControl.ItemContainerStyle>
      <Style>
             <Setter Property="Canvas.Left" Value="{Binding Metrics.Ordinate.X}"/>
             <Setter Property="Canvas.Top" Value="{Binding Metrics.Ordinate.Y}"/>
             <Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
       </Style>
 </ItemsControl.ItemContainerStyle>

到目前为止,一切都在按需运作。当用户悬停在边框上时,我在鼠标上方使用触发器来更改背景颜色,但由于UI已经如此依赖于颜色,我们认为悬停时我们希望边框的大小增加。所以我添加了比例变换:

 <Trigger Property="IsMouseOver" Value="True">
     <!--<Setter Property="Background" Value="{Binding SelectedTemplate.StandardBrush}"></Setter>-->
         <Setter Property="LayoutTransform">
               <Setter.Value>
                    <ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
                </Setter.Value>
          </Setter>
 </Trigger>

现在的问题是我需要在触发器中增加该单边框的ZIndex,以便随着它的增长而不会被附近的其他项目剪切。我正在搜索如何在触发器中设置XAML中的父项(ContentPresenter)并遇到this。这看起来很完美,除了内容演示者没有名称引用它,它是一个重复的控件,我无法理解我如何在XAML中引用它。

这是否可能在触发器内,或者我最好寻找一种不同的方法,要么不仅仅依赖于XAML,要么改变我的ItemsControl?

非常感谢提前。

修改

添加面板模板:

 <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <local:AutoSizeCanvas/>
            </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

AutoCanvas是一个自定义控件,它从Canvas派生,它覆盖了测量覆盖,因此它在滚动查看器中播放球,这是与标准Canvas的唯一区别。

修改

只是添加我正在使用绑定项目的数据模板,因为一些边框需要包含稍微不同的项目,David的当前答案确实有效,鼠标悬停在ZIndex上增加了,问题是所有项目它们的ZIndex增加了,所以如果鼠标越过一个意味着在后面的项目然后它被提升到顶部,这似乎也很慢。该解决方案确实有效但在这种情况下并不完全,因为它正在对所有项目进行全面设置,而不仅仅是需要触发器的一种类型的边框。本质上我有一个座位计划,我从另一个应用程序获取视觉数据,并且必须按原样使用它。该计划有区域,街区,行和座位,只有我想要触发的座位才会出现。

希望这很清楚。

2 个答案:

答案 0 :(得分:1)

你确定你需要增加ContentPresenter的ZIndex而不仅仅是Border的ZIndex吗?

如果是这样,那里你没有很多选择。我能看到的最好的方法是直接在itemsPresenter的样式中设置触发器。这样你就不必尝试找到边框的父级(我认为无论如何都不可能只在xaml中进行)

所以你最终得到这样的东西:

<ItemsControl.ItemContainerStyle>
    <Style>
        <Setter Property="Canvas.Left" Value="{Binding Metrics.Ordinate.X}"/>
        <Setter Property="Canvas.Top" Value="{Binding Metrics.Ordinate.Y}"/>
        <Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Canvas.ZIndex" Value="1000"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</ItemsControl.ItemContainerStyle>

答案 1 :(得分:0)

大卫的回答在我提供更多详细信息之前对我的原始问题是正确的,并且是一个非常好的答案,遗憾的是它在我的特殊场景中不起作用。

我设法解决了我的datatemplate边框背后的代码问题:

模板的XAML:

<DataTemplate DataType="{x:Type vm:Seat}">
    <Border CornerRadius="3" Width="{Binding Metrics.Size.Width}" Height="{Binding Metrics.Size.Height}" BorderThickness="2" MouseEnter="MouseEnter" MouseLeave="MouseLeave">
        <Border.RenderTransform>
            <ScaleTransform x:Name="ZoomTransform" ScaleX="1" ScaleY="1"/>
        </Border.RenderTransform>
        <Border.InputBindings>
            <MouseBinding Gesture="LeftClick" Command="{Binding LeftClickCommand}"/>
            <MouseBinding Gesture="RightClick" Command="{Binding RightClickCommand}"/>
        </Border.InputBindings>
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Setter Property="BorderBrush" Value="{Binding PriceBorderColour}"></Setter>
                <Setter Property="Background" Value="{Binding Template.StandardBrush}"></Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsSelected}" Value="True">
                        <Setter Property="Background" Value="{Binding SelectedTemplate.StandardBrush}"/>
                    </DataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsMouseOver}" Value="True"/>
                            <Condition Binding="{Binding Plan.EditModel.EditEnabled}" Value="True"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Cursor" Value="Pen"/>
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <Viewbox>
            <TextBlock Text="{Binding ObjectLabel.Text}" Foreground="{Binding ObjectLabel.FontColour}"/>
        </Viewbox>
    </Border>
</DataTemplate>

守则背后:

public partial class VisualDataTemplates : ResourceDictionary
{
    private Int32 _originalZIndex;
    private const Double _scaleSize = 1.5;
    private const Double _standardScaleSize = 1;

    public VisualDataTemplates()
    {
        InitializeComponent();
    }

    protected void MouseEnter(Object sender, RoutedEventArgs e)
    {
        Border border = sender as Border;
        ContentPresenter presenter = border.TemplatedParent as ContentPresenter;

        _originalZIndex = Canvas.GetZIndex(presenter);
        Canvas.SetZIndex(presenter, DisplayOrders.FrontItem);

        SetTransform(border, _scaleSize);
    }

    protected void MouseLeave(Object sender, RoutedEventArgs e)
    {
        Border border = sender as Border;
        ContentPresenter presenter = border.TemplatedParent as ContentPresenter;
        Canvas.SetZIndex(presenter, _originalZIndex);

        SetTransform(border, _standardScaleSize);

    }

    private void SetTransform(Border border, Double value)
    {
        ScaleTransform transform = border.RenderTransform as ScaleTransform;
        transform.ScaleX = transform.ScaleY = value;
    }
}

我现在唯一的问题是它很慢,所以我可能不得不完全放弃这个想法,并为悬停找到另一种视觉效果。

如果其他人有任何更好的想法,请提供。

由于