尝试将拖放重新排序应用于ItemsControl时崩溃

时间:2015-11-27 23:56:02

标签: c# .net wpf xaml

我正在尝试将拖放应用于ItemsControl上动态创建的按钮集合。我收到一个错误:

无法显式修改用作ItemsControl的ItemsPanel的Panel的Children集合。 ItemsControl为Panel生成子元素。

我不知道如何解决这个问题。

我的xaml:

<ItemsControl Grid.Row="2" Grid.Column="0" IsTabStop="False" Name="icsp"
              ItemsSource="{Binding Path=ContentButtons}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel x:Name="sp" AllowDrop="True" Background="SkyBlue" 
                        PreviewMouseLeftButtonDown="sp_PreviewMouseLeftButtonDown" 
                        PreviewMouseLeftButtonUp="sp_PreviewMouseLeftButtonUp" 
                        PreviewMouseMove="sp_PreviewMouseMove"
                        DragEnter="sp_DragEnter" Drop="sp_Drop"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

我的代码背后:

  public partial class Admin : UserControl
    {
        public Admin()
        {
            InitializeComponent();
        }
        private bool _isDown;
        private bool _isDragging;
        private Point _startPoint;
        private UIElement _realDragSource;
        private UIElement _dummyDragSource = new UIElement();

        private void sp_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var sp = FindChild<StackPanel>(Application.Current.MainWindow, "sp");
            if (e.Source == sp)
            {
            }
            else
            {              
                _isDown = true;                             
                _startPoint = e.GetPosition(sp);                       
            }
        }

        private void sp_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _isDown = false;
            _isDragging = false;
            _realDragSource.ReleaseMouseCapture();
        }

        private void sp_PreviewMouseMove(object sender, MouseEventArgs e)
        {          
            if (_isDown)
            {
                var sp = FindChild<StackPanel>(Application.Current.MainWindow, "sp");
                if ((_isDragging == false) &&
                    ((Math.Abs(e.GetPosition(sp).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
                     (Math.Abs(e.GetPosition(sp).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
                {
                    _isDragging = true;
                    _realDragSource = e.Source as UIElement;
                    _realDragSource.CaptureMouse();
                    DragDrop.DoDragDrop(_dummyDragSource, new DataObject("UIElement", e.Source, true),
                        DragDropEffects.Move);
                }
            }
        }

        private void sp_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("UIElement"))
            {
                e.Effects = DragDropEffects.Move;               
            }
        }

        private void sp_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("UIElement"))
            {
                var sp = FindChild<StackPanel>(Application.Current.MainWindow, "sp");
                UIElement droptarget = e.Source as UIElement;
                int droptargetIndex =-1, i =0;
                foreach (UIElement element in sp.Children)
                {
                    if (element.Equals(droptarget))
                    {
                        droptargetIndex = i;
                        break;
                    }
                    i++;
                }
                if (droptargetIndex != -1)
                {
                    sp.Children.Remove(_realDragSource);
                    sp.Children.Insert(droptargetIndex, _realDragSource);
                }

                _isDown = false;
                _isDragging = false;
                _realDragSource.ReleaseMouseCapture();
            }
        }

查找子项是一种用于搜索可视树并抓取名为sp的面板的方法。它工作并返回控件。当我将此代码应用于堆栈面板时,在xaml中创建的按钮一切正常。就在我尝试在ItemsControl中使用它时,它会爆炸。

0 个答案:

没有答案