我正在尝试将拖放应用于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中使用它时,它会爆炸。