5

我想在双击列表框中的项目时创建视觉效果。到目前为止,我有拖放功能,其中项目在视觉上附加到鼠标上并且可以移动到放置目标。通过该功能,我可以使用获取项目容器的相同逻辑为项目设置动画,但是我无法离开项目控制。有没有办法从 ListBox 中删除项目并将其视觉动画到另一个位置?基本上主列表框是一手牌。当一张卡片被双击时,我希望它在视觉上从手牌列表框移动到丢弃列表框。到目前为止,将项目从一个集合移动到另一个集合的逻辑没有问题,但是我真的想要这个事件的动画视觉表示。任何关于如何做这样的事情的想法或参考将不胜感激。

谢谢,布兰登

关于我尝试过的更多细节:有些概念我还没有很好地掌握,这导致我首先面对这堵墙。我有一个方法,我将 ListBox 作为 ItemsControl、作为列表框项的 FrameworkElement 以及与 ListBox 项关联的数据对象传入(有些可能是不必要的)。我试图做的是作为画布的 ListBoxItem 的 FindVisualChild。我能做到。在我看来,我想以某种方式将画布克隆为画布或位图,将其添加到同一位置的页面子级的子级中,从 ListBox 中删除 ListBoxItem,并将克隆动画到丢弃桩。当动画完成时,克隆将被移除或隐藏,并且随着该对象被添加到丢弃堆集合中,它将有效地替换克隆。

我的问题是,我觉得确实有一种更简单的方法可以使用装饰层或其他东西来做到这一点。我也不知道如何将克隆定位在元素中的完全相同的位置,在视觉树的更上方。我将继续努力并研究其他方法,我只希望有人能分享一些对此的见解。

4

3 回答 3

2

这是我为绘制位图视觉效果而编写的一些代码。您可以根据自己的需要进行调整,并通过装饰表示两个列表视图的共同祖先的 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;
        }
于 2009-01-07T02:00:06.483 回答
1

好的,您可以尝试获取一个 Visual 元素并将其背景设置为您的 ListItem 的视觉刷,并将其设置为另一个列表框。您可以等待故事板完成事件实际进行切换。如果这是我,我会从一个盒子动画到另一个盒子的边缘。如果切换发生得足够快,它对用户来说应该看起来非常无缝。根据您拥有的任何排序/过滤规则,找到项目应该进入列表框的确切位置将非常复杂。

于 2008-12-31T17:05:48.777 回答
1

如果两个列表框始终位于相同的位置,您可以尝试将双击的项目动画到预定位置,假设在旧列表和新列表之间的中间位置。然后执行代码将项目移动到新列表,但使用的样式会立即在该项目上启动动画,从该预定位置开始并动画到其在新列表中的位置。您可能必须在运行时根据它在列表中的插入位置调整新项目的初始偏移量。

于 2009-01-06T00:13:39.087 回答