【问题标题】:Dragable objects in WPF in an ItemsControl?ItemsControl中WPF中的可拖动对象?
【发布时间】:2010-07-30 22:34:58
【问题描述】:

我希望能够实现带有可拖动项目的 ItemsControl。 ItemsControl 的原因是我可以在后台绑定到我的 ViewModel。

我已经尝试在画布中使用拇指控件,它工作得很好,除非我将它粘贴到 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>

但是当我将它放在 ItemsControl 中时,它不再起作用。我假设 ItemsControl 正在注册鼠标事件并覆盖拇指?

任何人都有一个很好的解决方案来让它工作?

【问题讨论】:

    标签: c# wpf itemscontrol drag


    【解决方案1】:

    Ben 起初我认为这种方法行不通,但经过更多试验后,我明白了。

    问题可以归结为: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;
    

    【讨论】:

    • 谢谢!!我一直在努力找出DragDelta 将近一周的时间!你保存了我的项目!希望我能早点找到这篇文章。
    【解决方案2】:

    尝试通过样式设置 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>
    

    然后拇指变成:

    &lt;Thumb Style={StaticResource ThumbStyle}" ... /&gt;

    【讨论】:

    • 感谢您的回复,但这似乎有同样的问题。就好像画布在项目控件中不起作用一样。事件正在触发,我正在设置属性以在画布上移动它。
    猜你喜欢
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多