WPF的网格是一种可适应分辨率的布局,这种相对坐标的属性方便了我们开发,但是在一定程度上牺牲了绝对坐标的长处。我在开发过程中就遇到了这么一个棘手的问题:需要在一个网格布局的页面上写一个可交换元素位置的功能,该功能有如下三点需求:
1.实现元素交换位置;
2.交换位置的过程中第一个被拖拽的元素拖拽轨迹可视化;
3.保存已更新布局;
=======================================================
<Grid x:Name="BtnGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
</Window>
网格布局
===================================================
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
int count = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Button btn = new Button();
btn.Margin = new Thickness(1);
Grid.SetColumn(btn, j);
Grid.SetRow(btn, i);
count++;
btn.Name = "btn" + Convert.ToString(count);
btn.Content = btn.Name;
btn.PreviewMouseLeftButtonDown += Btn_PreviewMouseLeftButtonDown; //注册鼠标落下事件
btn.PreviewMouseLeftButtonUp += Btn_PreviewMouseLeftButtonUp;
BtnGrid.Children.Add(btn);//注册鼠标抬起事件
}
}
}
private int InitRow;
private int InitCol;
private UIElement InitUE;
private void Btn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var element = (UIElement)e.Source;
double y = e.GetPosition(BtnGrid).Y;
double start = 0.0;
int row = 0;
foreach (RowDefinition rd in BtnGrid.RowDefinitions)
{
start += rd.ActualHeight;
if (y < start)
{
break;
}
row++;
}
double x = e.GetPosition(BtnGrid).X;
double cstart = 0.0;
int column = 0;
foreach (ColumnDefinition cd in BtnGrid.ColumnDefinitions)
{
cstart += cd.ActualWidth;
if (x < cstart)
{
break;
}
column++;
}
UIElement uIElement = GetChildren(BtnGrid, row, column);
BtnGrid.Children.Remove(uIElement);
Grid.SetColumn(element, column);
Grid.SetRow(element, row);
BtnGrid.Children.Add(uIElement);
Grid.SetColumn(uIElement, InitCol);
Grid.SetRow(uIElement, InitRow);
Console.WriteLine("MouseLeftButtonUp {0} -- {1}", row, column);
}
private void Btn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
InitUE = (UIElement)e.Source;
InitCol = Grid.GetColumn(InitUE);
InitRow = Grid.GetRow(InitUE);
Console.WriteLine("MouseLeftButtonDown {0} -- {1}", InitRow, InitCol);
}
private UIElement GetChildren(Grid grid, int row, int column)
{
foreach (UIElement child in grid.Children)
{
if (Grid.GetRow(child) == row
&&
Grid.GetColumn(child) == column)
{
return child;
}
}
return null;
}
按钮交换位置逻辑