Анимировать ListBoxItem из одного ListBox в другой ListBox

Я хотел бы создать визуальный эффект при двойном щелчке по элементу в списке. Пока что у меня есть функция перетаскивания, при которой элемент визуально прикрепляется к мыши и может быть перемещен в цель перетаскивания. Благодаря этой функциональности я могу анимировать элемент, используя ту же логику получения контейнера элементов, однако я не могу оставить элемент управления элементами. Есть ли способ удалить элемент из ListBox и визуально оживить его в другом месте? По сути, основной список - это набор карт. При двойном щелчке по карте я хочу, чтобы она визуально перемещалась из окна списка рук в окно списка сброса. На данный момент с логикой перемещения элемента из одной коллекции в другую нет проблем, однако мне бы очень хотелось анимированного визуального представления этого события. Приветствуются любые идеи или ссылки на то, как сделать что-то подобное.

Спасибо, Брэндон

Дальнейшие подробности того, что я пытался: Есть некоторые концепции, которые я еще не очень хорошо понимаю, что заставило меня столкнуться лицом к лицу с этой стеной. У меня есть метод, который я передаю (некоторые могут быть ненужными) ListBox как ItemsControl, FrameworkElement, который является элементом списка, и объект данных, связанный с элементом ListBox. Я попытался сделать FindVisualChild из ListBoxItem, который является холстом. Я могу это сделать. На мой взгляд, я хотел как-то клонировать холст либо как холст, либо как растровое изображение, добавить его к дочерним элементам дочерней страницы в том же месте, удалить ListBoxItem из ListBox и анимировать клон для удаления куча. Когда анимация завершится, клон будет удален или скрыт, и когда этот объект будет добавлен в коллекцию сброса, он фактически заменит клон.

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


person BrandonS    schedule 17.12.2008    source источник
comment
Возможно, вы захотите прямо упомянуть, что вы говорите о WPF - тега недостаточно.   -  person bhollis    schedule 31.12.2008
comment
Это может не помочь вам полностью, но идея может помочь вам. http://bea.stollnitz.com/blog/?p=53   -  person Ray Booysen    schedule 06.01.2009
comment
Я использовал некоторые из этих концепций для реализации возможности перетаскивания. После достижения такого поведения я решил, что я также хочу иметь возможность дважды щелкнуть элемент, запускающий анимацию для другого ListBox. Ответ ниже аналогичен тому, как я его получил.   -  person BrandonS    schedule 13.01.2009


Ответы (3)


Вот код, над которым я работал, чтобы нарисовать визуализацию в растровом изображении. Вы можете адаптировать это к своим потребностям и нарисовать растровое изображение, украсив UIElement, который представляет общего предка двух представлений списка. Обратите внимание на использование FrameworkElement.TransformToAncestor для получения координат вложенного элемента в терминах элемента-предка.

        public static BitmapSource CreateBitmapFromElement(FrameworkElement element, Double dpiX, Double dpiY)
        {
            Size elementSize = new Size(element.ActualWidth, element.ActualHeight);
            Visual root = GetAdornerDecoratorAncestor(element);
            Rect elementBounds  = element.TransformToAncestor(root).TransformBounds(new Rect(elementSize));

            RenderTargetBitmap rtb = new RenderTargetBitmap((Int32)(elementBounds.Size.Width * dpiX / 96.0),
                                           (Int32)(elementBounds.Size.Height * dpiY / 96.0),
                                           dpiX,
                                           dpiY,
                                           PixelFormats.Pbgra32);

            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext dc = dv.RenderOpen())
            {
                VisualBrush vb = new VisualBrush(root);
                vb.ViewboxUnits = BrushMappingMode.Absolute;
                vb.Stretch = Stretch.None;
                vb.Viewbox = elementBounds;
                dc.DrawRectangle(vb, null, new Rect(new Point(), elementBounds.Size));
            }
            rtb.Render(dv);
            return rtb;
        }

        public static Visual GetAdornerDecoratorAncestor(DependencyObject obj)
        {            
            while(obj != null && !(obj is AdornerDecorator))
            {
                obj = VisualTreeHelper.GetParent(obj);
            }
            return obj as AdornerDecorator;
        }
person jlew    schedule 07.01.2009
comment
Это очень похоже на то, как я смог заставить эту идею работать так, как я задумал. Как только я визуализировал растровое изображение элемента, я смог анимировать его в фиксированном месте окна списка назначения. - person BrandonS; 13.01.2009

Хорошо, вы можете попробовать взять элемент Visual и установить его фон для visualbrush вашего ListItem и анимировать его в другом поле со списком. Вы можете дождаться события завершения раскадровки, чтобы переключиться. Если бы это был я, я бы анимировал из одного блока только до края другого. Если переключение происходит достаточно быстро, пользователю должно казаться, что оно не вызывает затруднений. Нахождение точной позиции того места, где должен находиться элемент в списке, было бы довольно сложным в зависимости от любых имеющихся у вас правил сортировки / фильтрации.

person Nick    schedule 31.12.2008

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

person Ben Reierson    schedule 06.01.2009