Выдвиньте элемент (Z Индекс) в Silverlight/WPF

Привет, здесь возможное решение с использованием только панд.

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

sorted_df = sorted_df = df.sort_values('Date')
result_df = sorted_df.groupby('A_key').apply(nearest_date_distance)

Так что теперь давайте посмотрим, что у нас есть внутри функции nearest_date_distance Функция основана на том факте, что Дата будет отсортирована, поэтому мы вычисляем время до даты и время до даты после, разницу между текущим днем ​​и следующим день отрицателен, поэтому мы добавляем .abs(). Наконец, мы берем минимум между этими двумя расстояниями (кстати, оператор min не примет пропущенное значение (NaT), которое у вас есть для первой строки time_to_before и последней строки времени после)

def nearest_date_distance(sub):
    time_to_before = sub['Date'].diff()
    time_to_after = sub['Date'].diff(-1).abs()
    nearest_date_distance = pd.concat([time_to_before, time_to_after],axis=1).min(axis=1)
    nearest_date_distance.name = 'Distance'
    return nearest_date_distance

Наконец, я немного соврал result_df, это будет MultiIndex Serie (не датафрейм) этой формы:

A_key  id
A1     0    145 days
       1    145 days
A2     2      0 days
       3      0 days
A3     4    163 days
       5     26 days
       6     26 days
A4     7      0 days
       8      0 days

Мы можем легко преобразовать его в DataFrame, и правильное именование нашего исходного индекса помогает увидеть, что все проиндексировано так же, как в оригинальном df.

result_df =sorted_df.groupby('A_key').apply(nearest_date_distance).reset_index(level=0)

    A_key   Distance
id      
0   A1  145 days
1   A1  145 days
2   A2  0 days
3   A2  0 days
4   A3  163 days
5   A3  26 days
6   A3  26 days
7   A4  0 days
8   A4  0 days

, и если вам нужна дата в итоговом кадре данных result_df['Date'] = df['Date'], то добейтесь цели:)

36
задан lisp 3 February 2014 в 08:53
поделиться

4 ответа

В WPF существует Панель. Свойство ZIndex, которое можно установить в триггере:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Resources>
        <x:Array x:Key="colors" Type="{x:Type Color}">
            <Color>Green</Color>
            <Color>Red</Color>
            <Color>Blue</Color>
            <Color>Orange</Color>
            <Color>Yellow</Color>
            <Color>Violet</Color>
        </x:Array>
        <DataTemplate DataType="{x:Type Color}">
            <Border x:Name="brd" Height="20" Width="20">
                <Border.Background>
                    <SolidColorBrush Color="{Binding}"/>
                </Border.Background>
                <Border.RenderTransform>
                    <ScaleTransform CenterX="10" CenterY="10"/>
                </Border.RenderTransform>
                <Border.Style>
                    <Style TargetType="{x:Type Border}">
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderThickness" Value="2"/>
                                <Setter Property="BorderBrush" Value="Black"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <Border.Triggers>
                    <EventTrigger RoutedEvent="Border.MouseEnter">
                        <BeginStoryboard>
                            <Storyboard>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.5"/>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.5"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Border.MouseLeave">
                        <BeginStoryboard>
                            <Storyboard>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1"/>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1"/>
                            </Storyboard>
                        </BeginStoryboard>
                  </EventTrigger>
                </Border.Triggers>
            </Border>
        </DataTemplate>
    <Style TargetType="{x:Type ContentPresenter}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Panel.ZIndex" Value="99999"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    </Grid.Resources>
    <ItemsControl ItemsSource="{StaticResource colors}" Margin="20" Width="40">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

В Style для ContentPresenter мы устанавливаем Panel.ZIndex на 99 999, когда IsMouseOver true. Это должно быть на ContentPresenter а не Border, потому что ContentPresenter с являются детьми ItemsControl панель.

, К сожалению, я не думаю, что это свойство добралось до Silverlight все же...

15
ответ дан Robert Macnee 27 November 2019 в 05:57
поделиться

Во-первых, приложенное свойство Zindex определяется в Холст и таким образом не доступно в других производных Панели.

ItemsControl заказывает подэлементы согласно порядку списка. Первый Объект у основания стека и последнего на вершине. С данным, все, что необходимо сделать, удостоверяется, что выбранный пункт находится в нижней части списка.

Первый создают интерфейс для упорядочивания. Как это:

interface IOrderable
    {
        int theZOrder{get;set;}
    }

Теперь реализация это в классе Вы показываете.

, Когда Вы захотите выявить объект, дайте ему высокое количество и дайте всем другим небольшое число.

Al там оставляют, фактическое упорядочивание. Добавьте что-то вроде этого, и Вы установлены:

ItemsCont.ItemsSource = 
            ItemsCont.Items.OrderByDesc(t=>((IOrderable)t).theZOrder);
2
ответ дан Sorskoot 27 November 2019 в 05:57
поделиться

Мне приходилось иметь дело с этим.

Допустим, у вас есть ItemsControl с ItemTemplate, установленным как экземпляр пользовательского элемента управления. В этом элементе управления вы выполняете Canvas.SetZIndex (this, 99). Это не сработает, потому что «this» не является непосредственным потомком ItemsPanel ItemsControl. ItemsControl создает ContentPresenter для каждого элемента, помещает его в ItemsPanel и отображает ItemTemplate в ContentPresenter.

Итак, если вы хотите изменить ZIndex в своем элементе управления, вам нужно найти его ContentPresenter и изменить ZIndex на том. Один из способов - это ...

        public static T FindVisualParent<T>( this DependencyObject obj )
        where T : DependencyObject
    {
        DependencyObject parent = VisualTreeHelper.GetParent( obj );
        while ( parent != null )
        {
            T typed = parent as T;
            if ( typed != null )
            {
                return typed;
            }
            parent = VisualTreeHelper.GetParent( parent );
        }
        return null;
    }
                ContentPresenter foo = this.FindVisualParent<ContentPresenter>();
            Canvas.SetZIndex( foo, 99 );
34
ответ дан 27 November 2019 в 05:57
поделиться

Html работает точно так же. Все элементы списка должны быть одноуровневыми, если вы хотите расположить их слоями.

Я расширил приведенный выше код, чтобы он останавливался, если нашел (например) ItemsPresenter. Если ContentPresenter не отображается между здесь и ItemsPresenter, то вернусь к моему исходному коду.

void setZindex(MyLayeredType layeredObj, int index) 
{
    ContentPresenter sibbling = 
    FindVisualParent<ContentPresenter, ItemsPresenter>(layeredObj);
    if (sibbling != null)
    {
        sibbling.SetValue(Canvas.ZIndexProperty, index);
    }
    else
    {
        layeredObj.SetValue(Canvas.ZIndexProperty, index);
    }
}

public static T FindVisualParent<T,C>(this DependencyObject obj)
where T : DependencyObject
where C : DependencyObject
{
    DependencyObject parent = VisualTreeHelper.GetParent(obj);
    while (parent != null)
    {
        T typed = parent as T;
        if (typed != null)
        {
            return typed;
        }
        C ceiling = parent as C;
        if (ceiling != null)
            return null;
        parent = VisualTreeHelper.GetParent(parent);
    }
    return null;
}
2
ответ дан 27 November 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: