这是我的第一篇文章所以请善待:D。
我正在寻找一种方法让我的程序的用户通过拖放将一个按钮(作为背景图像,并且是Grid-Children的内容)移动到另一个Grid-Children。
My Buttons由程序本身基于for-iteration中的数据库创建:
foreach (PC_Infos item in allPcsOnThisFloor)
{
if (item != null)
{
roomToCoordinates(allPcsOnThisFloor[i].Room,out column, out row);
Button btn = new Button();
btn.Name = Name+ "_Button";
btn.Background = new ImageBrush(my icon here);
btn.Click += btn_Click;
btn.SetValue(Grid.ColumnProperty, column);
btn.SetValue(Grid.RowProperty, row);
My_Grid.Children.Add (btn);
i++;
}
else
break;
}
PC_Infos
只是一个持有属性的类:PC_Name,Room和MAC_adress。
我的网格:
<Grid x:Name="Grid_10" AllowDrop="True">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\XXX\XXX\buildingPlan.png"/>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition />
[...]
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
[...]
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
现在有一种方法可以使用btn.*
在绘制时获取当前位置(行和列),另一个btn.*
在Grid-Child中创建此按钮的新副本当鼠标按下按钮时,鼠标当前是否已经结束?
或者甚至有办法将按钮从一个孩子“移动”到另一个孩子?
顺便说一句:我的程序应该显示一个建筑计划,其上有PC作为图标(按钮),在它们实际的位置。通过读取我的数据库中的“房间”列,源代码会进行粗略的猜测。但是房间不仅仅是一个地方。有人在门口的窗口工作,这应该由用户标记(拖放) 我在VS'13中使用了带有C#和.Net 4.5.1的WPF-Application。
PS:如果有人说:为什么网格和为什么地狱按钮? :D:当用户点击图标时,将显示具有系统值的新窗口,例如OS,RAM,CPU ....但我愿意接受任何实施。我现在还没有完成编程,所以我可能不知道最好的方法。希望你得到我的问题:D 谢谢你的帮助。如果有任何问题请问;)
答案 0 :(得分:0)
我可能会误解你的问题,但据我所见,这里没有任何拖延:你想在UIElements
周围移动Panel
。
首先,我建议使用Canvas
来显示您的商品,而不是Grid
,因为它会提供更大的灵活性。
假设您将此课作为主要对象:
public class PC_Infos
{
public string PC_Name;
public string Room;
public string MAC_Adress;
}
我不喜欢在代码隐藏中构建控件,而是喜欢一个简单的包装器,如:
public class DragablePC : INotifyPropertyChanged
{
public DragablePC(PC_Infos pc, double x = 0d, double y = 0d)
{
_pcItem = pc;
PcRow = y;
PcColumn = x;
}
private double _x;
public double PcColumn
{
get { return _x; }
set
{
if (value == _x) return;
_x = value;
RaisePropertyChanged("PcColumn");
}
}
private double _y;
public double PcRow
{
get { return _y; }
set
{
if (value == _y) return;
_y = value;
RaisePropertyChanged("PcRow");
}
}
PC_Infos _pcItem;
public DragablePC(PC_Infos pc, double x = 0d, double y = 0d)
{
_pcItem = pc;
PcRow = y;
PcColumn = x;
}
public override string ToString() { return _pcItem.PC_Name; }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
此包装器只存储X / Y坐标和您的项目。它允许定义绑定源,如下所示:
AllPCS = allPcsOnThisFloor.Select(p => new DragablePC(p));
现在,您可以使用ItemsControl
来显示您的商品。如上所述,我将Canvas
用于ItemsPanel
,并定义一个简单的ItemContainerStyle
将其放置在其上。
<ItemsControl Name="DDPanel" ItemsSource="{Binding Path=AllPCS}"
MouseMove="DDPanel_MouseMove">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" Background="LightGray"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=PcRow}"/>
<Setter Property="Canvas.Left" Value="{Binding Path=PcColumn}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type dnd:DragablePC}">
<Border BorderBrush="Red" BorderThickness="2" CornerRadius="6" Padding="6, 12"
Background="White" MinWidth="70"
MouseLeftButtonDown="Border_MouseLeftButtonDown"
MouseLeftButtonUp="Border_MouseLeftButtonUp">
<TextBlock Text="{Binding}" HorizontalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
必须更新ItemTemplate
以满足您的需求,最重要的部分是处理鼠标事件。
以下是我添加的处理程序:
DragablePC _selected = null;
Point cursorPos = new Point();
private void DDPanel_MouseMove(object sender, MouseEventArgs e)
{
if (null == _selected) return;
Point newPosition = e.GetPosition(DDPanel);
_selected.PcColumn += newPosition.X - cursorPos.X;
_selected.PcRow += newPosition.Y - cursorPos.Y;
cursorPos = newPosition;
}
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var uiItem = sender as FrameworkElement;
var dpc = uiItem.DataContext as DragablePC;
if (dpc == null) return;
cursorPos = e.GetPosition(DDPanel);
_selected = dpc;
}
private void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var uiItem = sender as FrameworkElement;
var dpc = uiItem.DataContext as DragablePC;
if (dpc == null) return;
_selected = null;
}
现在需要进行大量的调整,例如处理MouseLeave
事件,为定位添加一些逻辑......但是现在你可以移动你的电脑。
希望这有帮助。