C# 如何创建不带';带装饰元素的t刻度?

C# 如何创建不带';带装饰元素的t刻度?,c#,wpf,scale,adorner,C#,Wpf,Scale,Adorner,非常简单,我想创建一些调整大小/重新缩放装饰器,以附加到框架元素,如果用户正常使用装饰器,则允许用户调整元素大小,如果用户使用右下角装饰器并在执行此操作时按住SHIFT按钮,则允许用户重新缩放元素(不一定统一) 我尝试过各种方法来实现这一点,但我总是以装饰物本身被缩放而告终,所以它们最终会变得巨大,或者有着巨大的边界。此后,我开始使用相对于窗口的位置来定位它们,并忽略了应用于AdornedElement的RenderTransform,但是我得到了一些非常不寻常的行为 首先,当我将元素缩放超过(

非常简单,我想创建一些调整大小/重新缩放装饰器,以附加到框架元素,如果用户正常使用装饰器,则允许用户调整元素大小,如果用户使用右下角装饰器并在执行此操作时按住SHIFT按钮,则允许用户重新缩放元素(不一定统一)

我尝试过各种方法来实现这一点,但我总是以装饰物本身被缩放而告终,所以它们最终会变得巨大,或者有着巨大的边界。此后,我开始使用相对于窗口的位置来定位它们,并忽略了应用于AdornedElement的RenderTransform,但是我得到了一些非常不寻常的行为

首先,当我将元素缩放超过(大致)2倍时,重缩放行为会崩溃并开始到处跳跃。

很明显,这种行为更容易理解而不是描述,因此我附上了一个示例解决方案(VS2010),演示了问题和导致问题的代码

如果有人能给我指出正确的方向,请随时告诉我我做错了!哈哈

此外,请记住,如果底层装饰元素旋转,则最终也必须正确显示此装饰器,而目前它不会旋转


更新:为了让NVM满意,这里有一个解决方案:假设您在装饰器内有拇指用于拖动/旋转等,您首先要阻止它们缩放,因此您可以在GetDesiredTransform覆盖中执行此操作。应用已应用于框架图元的比例的倒数。这使得调整大小时拇指无法缩放


公共重写GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
double scaleFactor=GetCurrentScaleFactor(此.\u父级);
if(this.\u visualChildren!=null)
{
foreach(此处为var thumb.\u visualChildren.OfType())
{
thumb.RenderTransform
=新的ScaleTransform(1/scaleFactor,1/scaleFactor);
thumb.RenderTransferMorigin=新点(0.5,0.5);
}
}
返回base.GetDesiredTransform(转换);
}
下一个问题是排列拇指,使其在缩放/旋转等操作后位于正确的位置。由于已更改拇指的渲染变换,现在还必须使用ArrangeOverride手动排列

为此,请列出你所有的拇指以及它们应该处于的位置。如果你只处理正方形元素,你的工作就完成了一半,因为你只需要处理角和边

受保护的替代大小排列替代(大小最终化)
{
var adornedElement=this.adornedElement作为框架元素;
//使用装饰元素的宽度/高度等在此处排列拇指
//它已经有很长时间了,所以它的宽度/高度或实际宽度/实际高度
//您将需要使用。
这个._leftTopThumb.Arrange(让Rect在这里进行排列);
这个._rightopThumb.Arrange(让Rect在这里进行排列);
//等
返回最终化;
}
如果你不知道如何做的安排东西代码项目文章

如果您仍然无法让它工作,请向我们展示可能导致问题的相关代码(不是visual studio解决方案),我相信有人会帮助您

编辑

首先,简化代码以理解问题

  • 删除除BTMRightThumb之外的所有thumb和事件处理程序
  • 将DragCompleted事件添加到BTMRightThumb。(删除拖动三角形)
  • 基本上,问题代码的关键归结为注释行:

    void _btmRight_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        var adornedElement = AdornedElement as FrameworkElement;
        var hitThumb = sender as Thumb;
        if (adornedElement == null || hitThumb == null) return;
    
        var transformGroup = new TransformGroup();
        transformGroup.Children.Add(adornedElement.RenderTransform);
    
        //---- This is the problem line
        transformGroup.Children.Add(new ScaleTransform(1 + e.HorizontalChange / adornedElement.Width, 1 + e.VerticalChange / adornedElement.Height));
        //-------------------------------
    
        adornedElement.RenderTransform = new MatrixTransform(transformGroup.Value);
        }
    
    现在很容易解决这个问题。这段代码在您第一次拖动和调整大小时效果非常好。这是因为第一次拖动adornedElement.Width和adornedElement.Height时是正确的,因为尚未应用任何缩放变换。完成拖动后,假设宽度和高度现在将是新的宽度和高度<他们不是您可以看到这只是一个渲染变换,它不会更改元素的宽度或高度。它只是让它变得更大

    因此,您需要首先将现有的缩放变换应用于宽度和高度,以获得渲染的宽度和高度。然后使用这些新值计算缩放变换并添加到变换组。然后你会得到你想要的


    在DragDelta中执行此操作时,很可能仍然存在其他问题。但是在这种情况下,你应该问一个更具体的问题,只需要一点点相关的代码,我相信你会在几分钟内从某人那里得到答案。

    Siyfion,你所看到的现象是真实的。原因是在处理装饰器拖动时,没有使用相同的缩放进行补偿。除了NVM的答案外,请确保您还有以下内容:

    double deltaX = args.HorizontalChange / CurrentDisplayScaleX;
    double deltaY = args.VerticalChange / CurrentDisplayScaleX;
    

    以相同的方式获取当前显示比例。使用这些校正值,将停止跳跃。跳转实际上是双重绘图,首先由系统自动使用错误的比例,其次是使用您提供的修改后的正确尺寸。它出现在所有缩放级别,只是当缩放开始变大时,它变得非常明显。

    很有用,但是它几乎与我已经做的相同,并且与我的问题相同。。。我的建议来自于运行在超过200000台机器上的实时代码,它允许调整大小/旋转/移动/裁剪和其他许多事情。如果你不能让它工作,你就做错了。大胆提问并不能改善问题。用你所做的事情来显示你的代码将是非常有用的。猜猜看:你用的是什么形状的拇指(这是非常重要的),它们的模板看起来不同吗