WPF Grid new marquee feature

Sometimes there needs marquee, similar as EXCEL, draw a box inside the selected child controls.

 

 

After you select such as Border child controls can be set to red border

 

 

 Said that under the general principle of this feature. The background is a Grid, for example, which put a lot of Button. RectAngele a red border as well as to display box.

RectAngele not displayed by default.

When the left mouse button pressed, then record the mouse position as a starting point for the top left corner of RectAngele,

Hold down the mouse movement, mouse position as recorded at the lower right corner of the end RectAngele.

In this way two points, to determine the RectAngele position, hold down the mouse to move constantly, this RectAngele will be constantly changing size.

It uses several events

PreviewMouseMove,PreviewMouseLeftButtonDown,PreviewMouseLeftButtonUp。

 

Such features, of course, can be done XAML interface defined Grid Button RectRange of doing business layer .. If there are multiple interfaces do marquee features, would not you want to copy to copy the code to copy a few times? 

! This is too LOW, not endure, must be to control the level of abstraction, has nothing to do with the business logic.

 

New controls GridRect inherited Grid, the marquee feature is integrated into the controls inside. There is a critical place, Grid are likely to be divided into many Row and Clomn. Different Button in different ranks.

But the location of this RectRange actually ranks and irrelevant. It can not be fixed at a certain ranks. So RectRange to special treatment.

Ado, directly on the source code, can have it!

public  class GridRect: the Grid 
{ 
Private the Rectangle rect;
 Private the Grid rectgrid; // because it may be divided into many columns and rows, and the containers can not be rect packet parent 
public GridRect () 
{ 

Background = Brushes.Transparent;
 the this .Loaded + = GridRect_Loaded; 

} 

public  the delegate  void delegateSelectChildChange (List <FrameworkElement> SelectedControls); 

public delegateSelectChildChange SelectChildChange { GET ; SET ;} 

Private  void GridRect_Loaded ( ObjectSENDER, the RoutedEventArgs E) 
{ 
rectgrid = new new the Grid (); 
RECT = new new the Rectangle () 
{ 
the IsHitTestVisible = to false , 
StrokeThickness = . 1 , 
the Fill = Brushes.Transparent, 
the Visibility = System.Windows.Visibility.Collapsed, 
the Stroke = Brushes.Red, 
the HorizontalAlignment = System.Windows.HorizontalAlignment.Left, 
the VerticalAlignment = System.Windows.VerticalAlignment.Top 
}; 

// because it may be divided into many columns and rows, and the containers can not be rect parent packet
Grid.SetRowSpan(rectgrid, 100);
Grid.SetColumnSpan(rectgrid, 100);

rectgrid.Children.Add(rect);
this.Children.Add(rectgrid);

Panel.SetZIndex(rectgrid, 999);
}


#region 框选功能


protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
var StartPoint = e.GetPosition(this);
RectStartPoint.X = Math.Truncate(StartPoint.X);
RectStartPoint.Y = Math.Truncate(StartPoint.Y);

}

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Escape && rect.Visibility == Visibility.Visible)
{
rect.Visibility = Visibility.Collapsed;
}

}

private Point RectStartPoint = new Point();
private Point RectEndPoint = new Point();



protected override void OnPreviewMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.LeftButton == MouseButtonState.Pressed)
{
// This event will start at once after loading interface, because the mouse position relative to the grid will be updated, and Pressed, this time red box should not be displayed 
IF (rect.Visibility! = Visibility.Visible
 && RectStartPoint.X + RectStartPoint. ! the Y = 0 ) 
{ 
rect.Visibility = Visibility.Visible; 
} 

Point P = e.GetPosition ( the this ); 


Double width = Math.Truncate (the Math.Abs (of pX - RectStartPoint.X));
 Double height = Math.Truncate (the Math.Abs (pY & - RectStartPoint.Y)); 


rect.Margin = new new Thickness (RectStartPoint.X, RectStartPoint.Y, 0 , 0 ); 

rect.height = height;
rect.Width = width;

RectEndPoint.X = RectStartPoint.X + width;
RectEndPoint.Y = RectStartPoint.Y + height;

}
}

 

 

protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
if (rect.Visibility == Visibility.Visible)
{
List<FrameworkElement> SelectedControlsTmp=new List<FrameworkElement>();
foreach (FrameworkElement item in this.Children)
{
if (item == rect || item ==rectgrid)
{
continue;
}

GeneralTransform generalTransform1 = item.TransformToVisual(this);

 

Point lefttop = generalTransform1.Transform(new Point(0, 0));
Point rightbuttom = new Point(lefttop.X + item.ActualWidth, lefttop.Y + item.ActualHeight);

Point btnrighttop = new Point(rightbuttom.X, lefttop.Y);
Point btnleftbuttom = new Point(lefttop.X, rightbuttom.Y);


Rect rectTmp = new Rect(lefttop, rightbuttom);

Rect rectRed = new Rect(RectStartPoint, RectEndPoint);

if (rectTmp.IntersectsWith(rectRed))
{
SelectedControlsTmp.Add(item);
}
}
SelectChildChange?.Invoke(SelectedControlsTmp);
}
}

#endregion

}
View Code

 

Guess you like

Origin www.cnblogs.com/CSSZBB/p/11588931.html