2012-01-10 1 views
1

Я размещаю элементы из коллекции на холсте с помощью элемента ItemsControl. Позиционирование выполняется с помощью TranslateTransform: <TranslateTransform X="{Binding x}" Y="{Binding y}"/>. Чтобы сделать элементы доступными, я реализовал событие MouseLeftButtonUp для элементов.После размещения элемента ItemsControl на холсте получить его Transform (Silverlight 5)

Смотреть полный код ниже:

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

Моя идея состояла в том, чтобы получить это от отправителя события после отбрасывания отправителя обратно на эллипс, например. Ellipse myEllipse = (Ellipse)sender;, но я не вижу никаких свойств, содержащих эту информацию.

Если я использую GeneralTransform gt = myEllipse.TransformToVisual(Application.Current.RootVisual);, он дает мне Трансформирование относительно RootVisual, а не к сетке, на которой я опишу.

Возможно, я не замечаю здесь ничего очевидного. Я был бы благодарен за любой намек.

+0

Вы хотите найти й и y вашего переводного преобразования. Не связаны ли эти данные с DataContext? Просто получите DataContext и проверьте значения x и y. –

+0

Спасибо, Джош, как бы я это сделал? И после того, как у меня есть «DataContext», который является «ObservableCollection», скажем, тысячей элементов с значениями позиции x и y, как я узнаю, какой элемент соответствует тому, который я только что нажал? – Phasma

+0

Я нашел другое решение проблемы, см. Ниже. Если также возможно, как вы это описываете, Джош, я бы хотел больше узнать об этом. – Phasma

ответ

0

Я нашел решение. Для того, чтобы получить преобразование из 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

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

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

+0

Спасибо, Павел, но это не проблема. При нажатии на любой из элементов будут срабатывать соответствующие события мыши, вопрос заключается в том, что делать внутри функции триггера (например, внутри MouseLeftButtonUp), чтобы получить нужные мне данные. Кроме того, в Silverlight нет 'ItemsControl.ItemContainerStyle', поэтому я использую' Transform' для позиционирования элементов. – Phasma

+0

@Nuitari Ой, моя вина за «ItemContainerStyle». Черт, он существует в WPF. Почему его нет в SL ??? ... –

 Смежные вопросы

  • Нет связанных вопросов^_^