2010-07-30 5 views
3

Я хочу, чтобы иметь возможность осуществлять ItemsControl с перетаскиваемыми элементами. Причина для ItemsControl заключается в том, что я могу привязываться к моей ViewModel в фоновом режиме.Перетаскиваемые объекты в WPF в ItemsControl?

Я попытался использовать Thumb Control на холсте, и он отлично работает, за исключением случаев, когда я вставляю его в ItemsControl, он перестает работать. Вот то, что я пробовал:

 <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> 

Код позади:

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); 
    } 

И, наконец, мой 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")); 
     } 
    } 


} 

Когда я следующий на окне он работает отлично:

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

Но когда у меня это есть в I temsControl больше не работает. Я предполагаю, что ItemsControl регистрируется для событий мыши и переопределяет Thumb?

У кого-нибудь есть хорошее решение, чтобы получить работу?

ответ

6

Бен Я не думаю, что такой подход работал в первый, но после того, как более экспериментируя Я понял.

Проблема может быть сведена до: Canvas.Top и Canvas.Left не работают во время управления элементами. Но вы правы, что стиль - это способ обойти проблему. Вот решение, которое я придумал:

<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> 

И отделенный код:

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

настройки связывающие свойства Canvas с помощью стиля

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

</Style> 

Try Тогда большой палец становится:

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

+0

Спасибо за ответ, но это, кажется, имеет один и тот же вопрос. Как будто холст не работает во время контроля элементов. Событие запускается, и я устанавливаю свойства для перемещения его на холст. – Kelly