После размещения элемента ItemsControl на холсте, получите его Transform (Silverlight 5) - PullRequest
1 голос
/ 10 января 2012

Я позиционирую элементы из коллекции на холсте, используя 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, а не к сетке, на которой я рисую.

Возможно, я пропускаю что-то очевидное здесь.Буду благодарен за любую подсказку.

Ответы [ 2 ]

0 голосов
/ 11 января 2012

Я нашел решение. Чтобы получить преобразование UIElement (мой элемент), на который был нажат относительно другого UIElement (в моем случае Grid, на котором он находится, что также является LayoutRoot):

        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));
    }
0 голосов
/ 11 января 2012

Я не совсем уверен, в чем ваша проблема, но, думаю, я понял.

Вы используете очень странный подход к позиционированию предметов в Canvas. Это ваш подход, который делает так сложно получить поддержку кликов. Вы просто заставляете все свои вещи жить друг над другом. Вы просто визуализируете их в разных местах, в то время как системы компоновки и ввода думают, что все элементы находятся в начале системы координат. Вот почему все события мыши не работают.

Основной подход заключается в его прикрепленных свойствах Canvas.Left и Canvas.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 будет запущено только тогда, когда пользователь щелкнет по самому элементу, и вам не нужно будет вычислять позиции выбранных элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...