Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在画布上旋转动态创建的ListBoxItem?_C#_Wpf_Mvvm_Listbox_Rotation - Fatal编程技术网

C# 如何在画布上旋转动态创建的ListBoxItem?

C# 如何在画布上旋转动态创建的ListBoxItem?,c#,wpf,mvvm,listbox,rotation,C#,Wpf,Mvvm,Listbox,Rotation,在我的WPF MVVM应用程序中,我有一个ListBox,其中Canvas作为它的ItemsPanel。当用户单击按钮时,列表框的项目由用户动态创建—ListBox。ItemsSource是存储在myMainViewModel中的自定义类型的项目列表,myMainWindow是my主窗口的DataContext。我希望用户能够使用附加到每个ListBoxItem的一组Thumb控件旋转项目。到目前为止,我试图找到一个可行的解决方案几乎没有成功,我变得非常绝望 以下是我的ListBoxItem风格

在我的WPF MVVM应用程序中,我有一个
ListBox
,其中
Canvas
作为它的
ItemsPanel
。当用户单击按钮时,列表框的项目由用户动态创建—
ListBox。ItemsSource
是存储在my
MainViewModel
中的自定义类型的项目列表,my
MainWindow
是my
主窗口的
DataContext
。我希望用户能够使用附加到每个
ListBoxItem
的一组
Thumb
控件旋转项目。到目前为止,我试图找到一个可行的解决方案几乎没有成功,我变得非常绝望

以下是我的
ListBoxItem
风格中最重要的部分:


在这里你可以看到它的样子:

rotatedcorator
本质上只是一组稍微定制的
Thumb
控件(显示为图片中选定项目周围的小三角形),我想旋转我的
ListBoxItem
。但是我已经完全没有办法做这件事了。我只知道我需要编写合适的
DragDelta
DragStarted
方法作为事件处理程序。有什么办法可以缓解我的愤怒吗

编辑:以下是
DragStarted
DragDelta
旋转拇指的方法。它们会影响移动拇指的动作方式吗

拖动开始:

private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
    {
        var thumb = sender as RotateThumb;
        var parent = VisualTreeHelper.GetParent(thumb);
        for (int i = 0; i < 3; i++ )
        {
            parent = VisualTreeHelper.GetParent(parent);
        }
        this.designerItem = parent as ListBoxItem;

        if (this.designerItem != null)
        {
            this.designerCanvas = VisualTreeHelper.GetParent(this.designerItem) as Canvas;

            if (this.designerCanvas != null)
            {
                this.centerPoint = this.designerItem.TranslatePoint(
                    new Point(this.designerItem.Width * this.designerItem.RenderTransformOrigin.X,
                              this.designerItem.Height * this.designerItem.RenderTransformOrigin.Y),
                              this.designerCanvas);

                Point startPoint = Mouse.GetPosition(this.designerCanvas);
                this.startVector = Point.Subtract(startPoint, this.centerPoint);

                this.rotateTransform = this.designerItem.RenderTransform as RotateTransform;
                if (this.rotateTransform == null)
                {
                    this.designerItem.RenderTransform = new RotateTransform(0);
                    this.initialAngle = 0;
                }
                else
                {
                        this.initialAngle = this.rotateTransform.Angle;
                }
            }
        }
    }

EDIT2:问题已解决

有几种方法,但这里有一些伪代码可以帮助您开始:

// for every drag event
Point a = listboxitem center position (or wherever you want the rotation origin)
Point b = position before drag
Point c = position after drag

// calculate and normalize vectors a-b and a-c
Vector v1 = ( b - a ).Normalized();
Vector v2 = ( c - a ).Normalized();

// calculate angles for v1 and v2 (in radians)
double a1 = Math.Atan2( v1.y, v1.x );
double a2 = Math.Atan2( v2.y, v2.x );

// the amount of rotation is then the difference between a1 and a2
// NOTE: there's a catch here, Atan2 returns angles = -π ≤ θ ≤ π, so
// the values might wrap around, which you'll need to take care of too
double angleInRadians = a2 - a1;
double angleInDegrees = ( angleInRadians / Math.PI ) * 180.0;

然后将此角度添加到放置在
ListBoxItem

上的
旋转变换的角度中。是否可以在自定义项目类中包含命令和角度属性


如果是,请将模板旋转变换绑定到角度属性,并创建增加和减少角度的命令。

谢谢!我以前也接触过类似的代码(我使用的是在互联网上找到的一个示例),我已经设法让它工作了,但是,出现了另一个问题。当我翻转物品时,负责移动物品的拇指会发疯——变得非常敏感,朝相反方向移动物品并将其从画布中滑出。在其DragDelta中,我只需通过e.HorizontalChange和e.VerticalChange相应地更新项目的X和Y属性。唯一的区别是移动的拇指被放置在自定义类型的DataTemplate中。这可能是原因吗?嗯。是不是拇指旋转坐标系中给出的
DragDelta
可能?嗯,正如您在上面的样式中所看到的,我的自定义项目类的X和Y属性与
Canvas.Left/Canvas.Right
属性之间存在绑定。它是在移动项目时更新的自定义对象的坐标。旋转是否可能影响画布解释坐标的方式?无论如何,我已经在问题中加入了
DragDelta
DragStared
代码,如果您能看一下,我会很感激的。是的,这是一个有趣的想法。以后我会记住的,谢谢!
// for every drag event
Point a = listboxitem center position (or wherever you want the rotation origin)
Point b = position before drag
Point c = position after drag

// calculate and normalize vectors a-b and a-c
Vector v1 = ( b - a ).Normalized();
Vector v2 = ( c - a ).Normalized();

// calculate angles for v1 and v2 (in radians)
double a1 = Math.Atan2( v1.y, v1.x );
double a2 = Math.Atan2( v2.y, v2.x );

// the amount of rotation is then the difference between a1 and a2
// NOTE: there's a catch here, Atan2 returns angles = -π ≤ θ ≤ π, so
// the values might wrap around, which you'll need to take care of too
double angleInRadians = a2 - a1;
double angleInDegrees = ( angleInRadians / Math.PI ) * 180.0;