Установите ZIndex на родительский контент Presenter в триггере - PullRequest
2 голосов
/ 08 марта 2012

У меня есть ItemsControl, который имеет Canvas в виде ItemsPanel, элементы - это простые рамки, детали границ связаны с моделью представления, такими как X, Y ширина, высота, цвет и т. Д. Я скоро понял, что даже хотя я мог связать большинство данных, таких как размер и цвет, с самим элементом границы, я должен был связать точечные данные и ZIndex в стиле контейнера ItemsControl, но я считаю, что это потому, что эти свойства относятся только к тому ItemContainer, который является ContentPresenter:

<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>

До сих пор все работало как надо. Когда пользователь зависал над границами, я использовал триггер при наведении мыши, чтобы изменить цвет фона, но поскольку пользовательский интерфейс уже настолько зависел от цветов, мы решили, что для наведения курсора мы хотим, чтобы границы увеличивались в размере. Поэтому вместо этого я добавил масштабное преобразование:

 <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 этой единственной границы в триггере, чтобы при его увеличении он не ограничивался соседними элементами. Я искал, как установить родительский элемент (ContentPresenter) в XAML в триггере, и наткнулся на this . Это выглядит идеально, за исключением того, что в предъявителе контента нет имени, на которое можно сослаться, это повторный элемент управления, и я не могу понять, как я могу ссылаться на него в XAML.

Возможно ли это в триггере, или я лучше ищу другой подход, либо не основанный исключительно на XAML, либо, возможно, изменение моего ItemsControl?

Большое спасибо заранее.

Пол

Редактировать

Добавление шаблона панели:

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

AutoCanvas - это пользовательский элемент управления, производный от Canvas, который переопределяет переопределение меры, поэтому он воспроизводит мяч, находясь внутри прокрутки, что является единственным отличием от стандартного Canvas.

Редактировать

Просто добавьте, что я использую шаблоны данных для связанных элементов, так как некоторые границы должны содержать в себе немного отличающиеся элементы, текущий ответ Дэвида ниже работает, при наведении указателя мыши на ZIndex проблема заключается в том, что все элементы для них, находящимся над ним, значение ZIndex увеличено, поэтому, если мышь наводит курсор на элемент, который должен находиться сзади, он поднимается наверх, что также кажется очень медленным. Решение работает, но не совсем в этом сценарии, поскольку оно устанавливает общую настройку для всех элементов, а не только для одного типа границы, для которой требуется триггер. По сути, у меня есть план рассадки, который я получаю визуальные данные из другого приложения и должен использовать его как есть. В плане есть зоны, блоки, ряды и места. Я хочу, чтобы этот триггер срабатывал только для мест.

Надеюсь, это понятно.

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Вы уверены, что вам нужно увеличить ZIndex ContentPresenter, а не только ZIndex Border?

, если это так, у вас не так много вариантов.Лучшее, что я могу видеть, это настроить триггер прямо в стиле 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>
0 голосов
/ 08 марта 2012

Ответ Дэвида является правильным для моего первоначального вопроса, прежде чем я предоставил дополнительную информацию, и является совершенно хорошим ответом, к сожалению, он не сработал в моем специфическом сценарии.

Мне удалось решить проблему с кодом для моегограница таблицы данных:

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;
    }
}

Единственная проблема, которую я имею сейчас, заключается в том, что она медленная какчерт возьми, поэтому мне, возможно, придется полностью отказаться от этой идеи и найти другой визуальный эффект для парения.

Если у кого-то есть идеи получше, пожалуйста, предоставьте.

Спасибо

Пол

...