2010-07-30 3 views
3

Je veux être en mesure d'implémenter un ItemsControl avec des éléments pouvant être déplacés. La raison de ItemsControl est que je peux lier à mon ViewModel en arrière-plan.Objets pouvant être déplacés dans WPF dans ItemsControl?

J'ai essayé d'utiliser un contrôle de pouce dans une toile et cela fonctionne parfaitement, sauf que dès que je le colle dans un ItemsControl il cesse de fonctionner. Voici ce que j'ai essayé:

 <ItemsControl ItemsSource="{Binding MyItems}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Thumb Canvas.Left="0" Canvas.Top="0" Width="50" Height="50" DragDelta="MyThumb_DragDelta"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 

    </ItemsControl> 

Le code derrière:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = new MainViewModel(); 
    } 

    private void MyThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) 
    { 
     Canvas.SetLeft((UIElement)sender, Canvas.GetLeft((UIElement)sender) + e.HorizontalChange); 
     Canvas.SetTop((UIElement)sender, Canvas.GetTop((UIElement)sender) + e.VerticalChange); 
    } 

Et enfin mon ViewModel:

public class MainViewModel : DependencyObject 
{ 
    public ObservableCollection<Note> MyItems { get; set;} 


    public MainViewModel() 
    { 
     MyItems = new ObservableCollection<Note>(); 
     MyItems.Add(new Note(){Name="test"}); 
    } 

} 

public class Note : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string name; 

    public string Name 
    { 
     get { return name; } 
     set 
     { 
      name = value; 
      if(PropertyChanged!=null) PropertyChanged(this,new PropertyChangedEventArgs("Name")); 
     } 
    } 


} 

Quand je fais ce qui suit sur la fenêtre, il fonctionne très bien:

<Canvas> 
     <Thumb Canvas.Left="0" Canvas.Top="0" Width="50" Height="50" DragDelta="MyThumb_DragDelta"/>    
    </Canvas> 

Mais quand je l'ai dans un I temsControl ne fonctionne plus. Je suppose que ItemsControl est l'enregistrement pour les événements de la souris et le remplacement du pouce?

Quelqu'un at-il une bonne solution pour que cela fonctionne?

Répondre

6

Ben je ne pensais pas que cette approche a fonctionné au début, mais après plus d'expérimenter Je l'ai.

Le problème peut être réduit à: Canvas.Top et Canvas.Left ne fonctionnent pas dans un contrôle d'éléments. Mais vous avez raison de dire que le style est le moyen de contourner le problème. Voici la solution que je suis venu avec:

<ItemsControl ItemsSource="{Binding Notes}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Thumb Width="150" Height="150" DragDelta="Thumb_DragDelta" /> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Canvas.Left" Value="{Binding X}" /> 
       <Setter Property="Canvas.Top" Value="{Binding Y}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 

Et le codebehind:

public partial class MainWindow : Window 
{ 
    public ObservableCollection<Note> Notes { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = this; 

     Notes = new ObservableCollection<Note>(); 
     Notes.Add(new Note(){Title="test", X=100, Y=0}); 
    } 

    private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) 
    { 
     Note n = (Note)((FrameworkElement)sender).DataContext; 
     n.X += e.HorizontalChange; 
     n.Y += e.VerticalChange; 
    } 
} 

public class Note : INotifyPropertyChanged 
{ 
    private string title; 
    private double x; 
    private double y; 

    public double Y 
    { 
     get { return y; } 
     set 
     { 
      y = value; 
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Y")); 
     } 
    } 

    public double X 
    { 
     get { return x; } 
     set 
     { 
      x = value; 
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("X")); 
     } 
    } 


    public string Title 
    { 
     get { return title; } 
     set 
     { 
      title = value; 
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Title")); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
1

Essayez la configuration des propriétés de liaison toile par un style

<Style x:Key="ThumbStyle"> 
    <Setter Property="Canvas.Left" Value="{Binding Path=Left}"/> 
    <Setter Property="Canvas.Top" Value="{Binding Path=Top}"/> 
    <!-- more if required --> 

</Style> 

Puis le pouce devient:

<Thumb Style={StaticResource ThumbStyle}" ... />

+0

Merci pour la réponse, mais cela semble avoir le même problème. C'est comme si la toile ne fonctionnait pas dans un contrôle d'éléments. L'événement se déclenche et je définis les propriétés pour le déplacer sur la toile. – Kelly

Questions connexes