2010-08-24 5 views
1

Il y a un "champ" sur lequel certains éléments sont draggable:Silverlight 4: pourquoi les objets ne sont pas mobiles?

Voici un code XAML:

   <Canvas Height="180" Width="169" > 
        <Image Canvas.Left="0" Canvas.Top="0" Height="180" Width="149" 
          Source="../Picts/field.png" /> 

        <Pages:FieldItem x:Name="Item2" Canvas.Left="129" Canvas.Top="34" 
           MouseLeftButtonDown="Item1_OnMouseLeftButtonDown" 
           MouseLeftButtonUp="Item1_MouseLeftButtonUp" 
           MouseMove="Item1_MouseMove" 
           /> 
       </Canvas> 

et code-behind:

private bool bIsCaptured = false; 
    double mouseVerticalPosition; 
    double mouseHorizontalPosition; 

    private void Item1_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     ((FrameworkElement)sender).CaptureMouse(); 
     bIsCaptured = true; 
     mouseVerticalPosition = e.GetPosition(null).Y; 
     mouseHorizontalPosition = e.GetPosition(null).X; 
    } 

    private void Item1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (bIsCaptured) 
     { 
      UserControl item = sender as UserControl; 
      if (item != null) 
      { 
       // Calculate the current position of the object. 
       double deltaV = e.GetPosition(null).Y - mouseVerticalPosition; 
       double deltaH = e.GetPosition(null).X - mouseHorizontalPosition; 
       double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty); 
       double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty); 

       // Set new position of object. 
       item.SetValue(Canvas.TopProperty, newTop); 
       item.SetValue(Canvas.LeftProperty, newLeft); 

       // Update position global variables. 
       mouseVerticalPosition = e.GetPosition(null).Y; 
       mouseHorizontalPosition = e.GetPosition(null).X; 
      } 
     } 
    } 

    private void Item1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     UserControl item = sender as UserControl; 
     bIsCaptured = false; 
     if (item != null) 
     { 
      item.ReleaseMouseCapture(); 
     } 
    } 

Ma tâche est d'afficher une collection d'éléments liés à une liste d'objets. Comment faire est décrit dans le sujet: Silverlight 4: how to display list of custom controls (not in list order).

Le seul manque de l'approche proposée est la suivante: les articles ne sont pas draggable plus ...

ici si la mise à jour du code XAML des contrôles « titulaire » (fournie à des fins de cohérence):

<Canvas Height="180" Width="169" Background="Beige" HorizontalAlignment="Center" > 
      <Image Canvas.Left="0" Canvas.Top="0" Height="180" Width="149" 
        Source="../Picts/field.png" /> 
      <Pages:MyItemsControl ItemsSource="{Binding SquadFieldPlayers}"> 
       <Pages:MyItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <Canvas Height="180" Width="169" Background="Transparent" 
           HorizontalAlignment="Center" /> 
        </ItemsPanelTemplate> 
       </Pages:MyItemsControl.ItemsPanel> 
       <Pages:MyItemsControl.ItemTemplate> 
        <DataTemplate> 
         <Pages:FieldItem 
          MouseLeftButtonDown="Item1_OnMouseLeftButtonDown" 
          MouseLeftButtonUp="Item1_MouseLeftButtonUp" 
          MouseMove="Item1_MouseMove" 
          /> 
        </DataTemplate> 
       </Pages:MyItemsControl.ItemTemplate> 
      </Pages:MyItemsControl > 
     </Canvas> 

Tous les gestionnaires d'événements de souris sont appelés, mais les éléments ne sont pas vraiment mobiles ... pourquoi?

+0

Vous voulez seulement que le contrôle FieldItem soit mobile? –

+0

Oui, chaque FieldItem devrait pouvoir être déplacé par la souris. Aussi, j'aimerais que l'objet de données soit notifié lorsque la position de l'objet a changé – Budda

Répondre

1

Je ne sais toujours pas comment cela devrait fonctionner, mais j'ai trouvé une solution de contournement. La méthode 'Item1_MouseMove' a été mise à jour pour effectuer les opérations suivantes:

  1. Rechercher l'objet de données auquel le contrôle est lié;
  2. Définissez les propriétés 'FieldCoordX' et 'FieldCoordY' de cet objet au lieu de définir 'Canvas.LeftProperty' et 'Canvas.RightProperty' du contrôle.

Il ressemble à ceci:

private void Item1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (bIsCaptured) 
     { 
      FrameworkElement element = sender as FrameworkElement; 
      if (element != null) 
      { 
       ISquadPlayerViewModel vmPlayer = element.DataContext as ISquadPlayerViewModel; 
       if (vmPlayer != null) 
       { 
        // Calculate the current position of the object. 
        double deltaH = e.GetPosition(null).X - mouseHorizontalPosition; 
        double deltaV = e.GetPosition(null).Y - mouseVerticalPosition; 
        double newLeft = deltaH + vmPlayer.FieldCoordX; 
        double newTop = deltaV + vmPlayer.FieldCoordY; 

        // Set new position of object. 
        vmPlayer.FieldCoordX = newLeft; 
        vmPlayer.FieldCoordY = newTop; 
       } 

       // Update position global variables. 
       mouseVerticalPosition = e.GetPosition(null).Y; 
       mouseHorizontalPosition = e.GetPosition(null).X; 
      } 
     } 
    } 

Un autre élément à ajouter dans la description originale, la personnalisation de l'objet 'ItemsControl' qui accueille tous les contrôles:

public class MyItemsControl : ItemsControl 
{ 
    protected override void PrepareContainerForItemOverride(
            DependencyObject element, object item) 
    { 
     FrameworkElement contentitem = element as FrameworkElement; 
     if (contentitem != null) 
     { 
      Binding leftBinding = new Binding("FieldCoordX"); 
      Binding topBinding = new Binding("FieldCoordY"); 
      leftBinding.Mode = BindingMode.TwoWay; 
      topBinding.Mode = BindingMode.TwoWay; 
      contentitem.SetBinding(Canvas.LeftProperty, leftBinding); 
      contentitem.SetBinding(Canvas.TopProperty, topBinding); 

      base.PrepareContainerForItemOverride(element, item); 
     } 
    } 
} 

Comme vous pouvez voir nos contrôles sont déjà liés aux propriétés des objets de données. Nous avons donc besoin de mettre à jour non pas une donnée de contrôle, mais des données d'objet.

Si quelqu'un est intéressé par plus de détails, demandez. Je vais essayer d'aider.

Questions connexes