我正在做一个绘图应用程序。因为我想要与数学图相同的行为,所以我将以下转换应用于具有数据点的画布:
<UserControl.Resources>
<TransformGroup x:Key="CanvasTransform">
<TranslateTransform X="30" Y="30"/>
<ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5" />
</TransformGroup>
</UserControl.Resources>
以下是使用的转换:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.RenderTransformOrigin>
<Point X="0.5" Y="0.5"/>
</Canvas.RenderTransformOrigin>
<Canvas.RenderTransform>
<Binding Source="{StaticResource CanvasTransform}"/>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
到目前为止还不错。问题在于向绘图中添加点。因为鼠标单击事件正在返回窗口坐标中的位置,所以没有用。该点添加到错误的位置,因为它在添加后会发生变换。
例如,Canvas有400个单元高。我单击左上角鼠标位置是[X=10, Y=10]
此点被添加到绘图并渲染。渲染转换然后使用[10,10]点并计算它的新位置:[X=40, Y=360]
(窗口坐标)。
这意味着我在上角单击,该点出现在下角。这实际上是正确的行为。
我的问题是,如何在存储点之前手动应用渲染变换,这样点就会出现在鼠标下。
到目前为止,我尝试了以下方法:
var trans = Resources["CanvasTransform"] as TransformGroup;
var mouse = e.GetPosition(this); // mouse position relative to canvas
var newPoint = trans.Transform(mouse);
但是在这个变换之后,newPoint有以下坐标。我再次知道为什么结果是这样。转换的原点是0,0,转换是29,可能是由于舍入误差。
现在我可以取这个新点并手动更改值-从X坐标中减去30
,然后添加Canvas。ActualHeight
到Y坐标,这将固定位置。
但那又有什么意义呢?
我的问题是:有没有可能像渲染器那样应用渲染转换,以避免手动摆弄坐标?
>
不需要ScaleTransform中的CenterX=.5“CenterY=.5”
。它所做的只是添加一个微小的平移变换(半像素)。
要从变换后的位置获取源位置,需要使用逆变换(Transform的属性)。这就是X-30错误的来源。
要更改转换原点,您需要首先减去一半画布大小,然后进行转换,然后添加一半画布大小。
var origin = new Point(lstItems.ActualWidth / 2, lstItems.ActualHeight / 2);
var transform = ((TransformGroup)Resources["CanvasTransform"]).Clone();
transform.Children.Insert(0, new TranslateTransform(-origin.X, -origin.Y));
transform.Children.Add(new TranslateTransform(origin.X, origin.Y));
_transform = transform.Inverse;
完整样品:
主窗口。xaml
<Window x:Class="So21501609WpfMouseRenderTransform.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Control.Resources>
<TransformGroup x:Key="CanvasTransform">
<TranslateTransform X="30" Y="30"/>
<ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5"/>
</TransformGroup>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="SkyBlue"/>
</Style>
</Control.Resources>
<ItemsControl x:Name="lstItems" MouseDown="LstItems_OnMouseDown" Width="400" Height="400" Background="Transparent">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.RenderTransformOrigin>
<Point X="0.5" Y="0.5"/>
</Canvas.RenderTransformOrigin>
<Canvas.RenderTransform>
<Binding Source="{StaticResource CanvasTransform}"/>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<TextBlock Canvas.Left="10" Canvas.Top="10" Text="10 10"/>
<TextBlock Canvas.Left="10" Canvas.Top="300" Text="10 300"/>
<TextBlock Canvas.Left="300" Canvas.Top="300" Text="300 300"/>
<TextBlock Canvas.Left="300" Canvas.Top="10" Text="300 10"/>
</ItemsControl.Items>
</ItemsControl>
</Window>
主indow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace So21501609WpfMouseRenderTransform
{
public partial class MainWindow
{
private GeneralTransform _transform;
public MainWindow ()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded (object sender, RoutedEventArgs routedEventArgs)
{
var origin = new Point(lstItems.ActualWidth / 2, lstItems.ActualHeight / 2);
var transform = ((TransformGroup)Resources["CanvasTransform"]).Clone();
transform.Children.Insert(0, new TranslateTransform(-origin.X, -origin.Y));
transform.Children.Add(new TranslateTransform(origin.X, origin.Y));
_transform = transform.Inverse;
}
private void LstItems_OnMouseDown (object sender, MouseButtonEventArgs e)
{
Point pos = _transform.Transform(e.GetPosition(lstItems));
var item = new TextBlock { Text = pos.ToString() };
Canvas.SetLeft(item, pos.X);
Canvas.SetTop(item, pos.Y);
lstItems.Items.Add(item);
}
}
}
问题内容: 例如,我在中有一个局部,我想在几个地方使用不同的汽车集合来渲染它。也许是这样的: 与常规包含项的主要区别在于,部分显示项不需要了解其要显示的汽车列表的任何信息。给了它一系列汽车,并显示它们。可能像: 问题答案: 该指令在父作用域和子作用域中重命名的“本地”变量之间提供了2路数据绑定。它可以与其他指令结合使用,例如实现出色的模板可重用性。需要AngularJS 1.2.x 标记 这是怎么
我想将鼠标移动到某个位置(0,0)。在上一次点击操作之后,我实际上需要将鼠标从该位置移开,因为它会干扰我需要执行的下一个操作。 我发现遵循Java代码这是一个完美的起点,但我无法将其翻译成VBA并适应我的需要。 资料来源: 如何使用Java在Selenium WebDriver中执行鼠标悬停功能? https://www.guru99.com/keyboard-mouse-events-files
我正试图通过使用在中显示一个带有QT的Coin3D/Open Inventor场景,我需要帮助将其转换为 到目前为止,我尝试的是将场景渲染到中,并获得如下缓冲区: 然后从缓冲区数据创建一个: 这是正确的方法吗? 正如在这个关于绘制图像的问题中所描述的,如果源是一张图片,我就能够绘制它。 e:为了确保我的缓冲区实际上包含一个场景,我将缓冲区内容写入两个文件。例如,您可以使用Irfan View及其插
有什么想法吗?提前谢了。
问题内容: 我从JNI调用中获取了一个字节数组,并试图用它构造一个Bitmap对象。 我的问题是,以下代码返回空值。 有什么提示吗? PS:像素布局是BGR,而不是RGB。 问题答案: 该解码字节数组确实不适用于此格式。我从BGR手动更改为RGB。 然而, 可以引起: 08-29 14:34:23.460:错误/ AndroidRuntime(8638):java.lang.ArrayIndexO
问题内容: 我目前正在用Java开发程序,仅当用户同时用鼠标左键和右键单击时,才必须触发特定事件。 由于这有点不合常规,因此我决定首先进行测试。这里是: 我对其进行了测试,并且可以正常工作,但是存在问题。 如您所见,鼠标左键由表示,鼠标右键由表示。 如果用户的鼠标没有滚轮(显然仍然存在此类鼠标),则在MouseEvent中仅设置两个按钮。这是否意味着右键将由代替?如果是,如何更改代码以适应此要求?