【问题标题】:After placing ItemsControl item on canvas, get its Transform (Silverlight 5)在画布上放置 ItemsControl 项目后,获取它的变换(Silverlight 5)
【发布时间】:2012-01-10 18:27:16
【问题描述】:

我使用 ItemsControl 将集合中的项目放置在画布上。定位由 TranslateTransform 完成:<TranslateTransform X="{Binding x}" Y="{Binding y}"/>。为了使项目可点击,我在项目上实现了 MouseLeftButtonUp 事件。

查看下面的完整代码:

<ItemsControl ItemsSource="{Binding XYPoints}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Width="20" Height="20" Fill="Red" MouseLeftButtonUp="XYPlotPoint_MouseLeftButtonUp">
                <Ellipse.RenderTransform>
                    <TransformGroup>
                        <RotateTransform Angle="0"/>
                        <TranslateTransform X="{Binding x}" Y="{Binding y}"/>
                    </TransformGroup>
                </Ellipse.RenderTransform>
                </Ellipse >
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

我想不通的是:我希望能够单击我的任何项目并获取 TranslateTransform 坐标,即用于在画布上定位元素的 x 和 y 值。

我的想法是在将发送者转换回椭圆后从事件的发送者那里得到这个,例如Ellipse myEllipse = (Ellipse)sender; 但我没有看到任何包含该信息的属性。

如果我使用GeneralTransform gt = myEllipse.TransformToVisual(Application.Current.RootVisual);,它只会给我相对于 RootVisual 的变换,而不是相对于我正在绘制的网格。

也许我在这里忽略了一些明显的东西。如有任何提示,我将不胜感激。

【问题讨论】:

  • 您想找到翻译转换的 x 和 y 值。那些不是从您的 DataContext 绑定的吗?只需获取 DataContext 并检查 x 和 y 值。
  • 谢谢乔希,我该怎么做?在我拥有DataContext 之后,这是一个ObservableCollection,例如,一千个具有 x 和 y 位置值的项目,我怎么知道哪个项目对应于我刚刚单击的项目?
  • 我找到了另一个解决问题的方法,见下文。如果你描述的方式也是可能的,乔希,我想了解更多。

标签: silverlight position mouseevent transform itemscontrol


【解决方案1】:

我不太确定你的问题是什么,但我想我明白了。

您正在使用一种非常奇怪的方法来定位 Canvas 中的项目。是您的方法使得获得点击支持变得如此困难。你只是让你所有的项目相互重叠。你只是在不同的地方渲染它们,而布局和输入系统认为所有项目都在坐标系原点。这就是为什么所有鼠标事件都不起作用的原因。

主流方法是通过其附加属性Canvas.LeftCanvas.Top,如MSDN 所示。尝试通过ItemContainerStyle绑定属性:

<ItemsControl ItemsSource="{Binding XYPoints}">

  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas/>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Ellipse Width="20" Height="20" Fill="Red" MouseLeftButtonUp="XYPlotPoint_MouseLeftButtonUp"/>
    </DataTemplate>
  </ItemsControl.ItemTemplate>

  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Canvas.X" Value="{Binding x, Mode=TwoWay}"/>
      <Setter Property="Canvas.Y" Value="{Binding y, Mode=TwoWay}"/>
    </Style>
  </ItemsControl.ItemContainerStyle>

</ItemsControl>

一旦你这样做了,你的MouseLeftButtonUp事件只会在用户点击这个项目时被触发,你不需要计算被点击项目的位置。

【讨论】:

  • 谢谢帕维尔,但这不是问题所在。单击任何项​​目都会触发相应的鼠标事件,问题是在触发函数内部(例如在 MouseLeftButtonUp 内部)做什么来获取我想要的数据。此外,Silverlight 中没有 ItemsControl.ItemContainerStyle,这就是为什么我使用 Transform 来定位项目。
  • @Nuitari 哎呀,“ItemContainerStyle”是我的错。该死的,它存在于WPF中。为什么SL里没有???...
【解决方案2】:

我找到了解决方案。要获得相对于另一个UIElement(在我的情况下是放置在Grid,也是LayoutRoot)上单击的UIElement(我的项目)的转换:

        private void XYPlotPoint_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        //cast sender to original type
        Ellipse myEllipse = (Ellipse)sender;

        //get the transform relative to the LayoutRoot
        GeneralTransform gt = myEllipse.TransformToVisual(LayoutRoot);

        //transform a new point to get the coordinates
        var myUiElementPosition = gt.Transform(new Point(0, 0));
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2011-01-21
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多