using BPASmartClient.Compiler; using Microsoft.Toolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace BPASmartClient.SCADAControl.CustomerControls { /// /// FYFTheListBox.xaml 的交互逻辑 /// public partial class FYFTheListBox : UserControl, IExecutable { /// /// 数据model /// public ListBoxDataModel TheListBoxModel = new ListBoxDataModel(); public event EventHandler PropertyChange; //声明一个事件 ListView listView = null; public FYFTheListBox() { InitializeComponent(); this.SizeChanged += Silos_SizeChanged; } private void Silos_SizeChanged(object sender, SizeChangedEventArgs e) { if (listView == null) { foreach (ListView tb in Utils.FindVisualChildren(this)) { // do something with tb here listView = tb; listView.PreviewMouseMove += ListView_PreviewMouseMove; listView.PreviewMouseLeftButtonUp += lisbox_PreviewMouseLeftButtonUp; listView.PreviewMouseLeftButtonDown += ListView_PreviewMouseLeftButtonDown; TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "二货", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "张三1", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "李四2", Ph = "125486545" }); TheListBoxModel.ViewItems.Add(new ItemModel { Name = "王麻子3", Ph = "125486545" }); this.DataContext = TheListBoxModel; } } } public string ControlType => "控件"; private bool isExecuteState; public bool IsExecuteState { get { return isExecuteState; } set { isExecuteState = value; if (IsExecuteState) { Register(); } } } public void Register() { } #region 移动事件 /// /// 当前拖动子控件流 /// private UIElement ChildElement; /// /// 当前拖拽子控件Item /// private ListBoxItem ChildListBoxItem; /// /// 是否已经按下 /// private bool isDown = false; /// /// 当前拖动的Pop窗体 /// private Popup DropPopup = null; /// /// 鼠标按下事件 /// /// /// /// private void ListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { //isDown变量是防止多次操作。 if (isDown) { isDown = false; return; } var pos = e.GetPosition(listView); HitTestResult result = VisualTreeHelper.HitTest(listView, pos); if (result != null) { ChildElement = Utils.FindVisualParent(result.VisualHit); if (ChildElement != null) { ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。 ChildListBoxItem = Utils.FindVisualParent(VisualTreeHelper.HitTest(ChildElement, e.GetPosition(ChildElement)).VisualHit); //创建一个Pop,表明拖拽开始 CreatePopup(ChildElement, e); isDown = true; } } } catch (Exception ex) { } } /// /// 鼠标按下事件-->暂时不用 /// /// /// private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { //isDown变量是防止多次操作。 if (isDown) { isDown = false; return; } ChildElement = (UIElement)sender; ChildElement.CaptureMouse();//设置了鼠标捕获,这样它可以不受到其它控件的影响。 ChildListBoxItem = Utils.FindVisualParent(VisualTreeHelper.HitTest(ChildElement, e.GetPosition(ChildElement)).VisualHit); //创建一个Pop,表明拖拽开始 CreatePopup(ChildElement, e); isDown = true; } catch (Exception ex) { } } /// /// 鼠标抬起事件 /// /// /// private void lisbox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { try { //鼠标未按下返回 if (!isDown) return; isDown = false; //关闭Pop窗体 if (this.DropPopup != null) { this.DropPopup.IsOpen = false; this.DropPopup.Child = null; this.DropPopup = null; } //蒙层关闭,表明结束拖拽 MoveListBoxStyle(null, false); //当控件具有鼠标捕获的话,则释放该捕获。 ChildElement.ReleaseMouseCapture(); } catch (Exception ex) { } } /// /// 鼠标移动事件 /// /// /// private void ListView_PreviewMouseMove(object sender, MouseEventArgs e) { try { if (isDown == false) return; if (e.LeftButton != MouseButtonState.Pressed) lisbox_PreviewMouseLeftButtonUp(null, null); Point ptLeftUp = new Point(0, 0); Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight); ptLeftUp = this.PointToScreen(ptLeftUp); ptRightDown = this.PointToScreen(ptRightDown); double y = e.GetPosition(this).Y; double x = e.GetPosition(this).X; if (DropPopup != null)//下面两句是设置Popup控件的位置除以2是想让鼠标在它的中心 { DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)ChildElement).ActualWidth / 2; DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)ChildElement).ActualHeight / 2; } //蒙层打开,表明拖拽开始,设置透明度和显示状态 MoveListBoxStyle(e, true); } catch (Exception ex) { } } /// /// 移动效果 /// /// private void MoveListBoxStyle(MouseEventArgs e, bool isBool) { try { if (isBool)//为真,根据鼠标位置设置行透明度和显示状态 { //移动到某行减轻某行 暗黑 foreach (ListBoxItem item in Utils.FindVisualChildren(listView)) { if (item != ChildListBoxItem)//这就是其他控件 { double item_width = item.ActualWidth; //当前行宽 double item_height = item.ActualHeight; //当前行高 double item_x = e.GetPosition(item).X; //鼠标相对当前行X位移 double item_y = e.GetPosition(item).Y; //鼠标相对当前行Y位移 if (item_y <= item_height && item_y > 0 && item_x > 0 && item_x <= item_width)//鼠标进入哪一行,则将那一行变灰 { item.Opacity = 0.5; int lao_index = TheListBoxModel.ViewItems.IndexOf(item.Content as ItemModel); int new_index = TheListBoxModel.ViewItems.IndexOf(ChildListBoxItem.Content as ItemModel); TheListBoxModel.ViewItems.Move(lao_index, new_index); } else //鼠标没在哪一行,则保持原状 { item.Opacity = 1; } } else { item.Visibility = Visibility.Hidden; } } } else//为假 恢复所有行透明度和显示状态 { //移动到某行减轻某行 暗黑 foreach (ListBoxItem item in Utils.FindVisualChildren(listView)) { item.Opacity = 1; item.Visibility = Visibility.Visible; } } } catch (Exception ex) { } } /// /// 创建浮动窗口 /// /// /// private void CreatePopup(Visual dragElement, MouseButtonEventArgs e) { //使用PointToScreen函数可以将点转换为屏幕坐标 //首先获取当前窗体的左上角和右下角两点的坐标 Point ptLeftUp = new Point(0, 0); //转换获取到这个窗口相对于屏幕两个坐标 ptLeftUp = this.PointToScreen(ptLeftUp); //获取myGrid的实际宽高,主 double y = e.GetPosition(this).Y; double x = e.GetPosition(this).X; //拖拽Popup框 this.DropPopup = new Popup(); Border border = new Border(); border.Margin = new Thickness(0, 0, 8, 8); DropShadowEffect effect = new DropShadowEffect(); effect.Opacity = 1; effect.ShadowDepth = -14; effect.BlurRadius = 9; effect.Color = Color.FromArgb(100, 0, 0, 0); border.Effect = effect; //矩阵框 Rectangle r = new Rectangle(); r.Width = ((FrameworkElement)dragElement).ActualWidth; r.Height = ((FrameworkElement)dragElement).ActualHeight; r.Fill = new VisualBrush(dragElement); border.Child = r; this.DropPopup.Child = border; DropPopup.AllowsTransparency = true; DropPopup.HorizontalOffset = ptLeftUp.X + x - ((FrameworkElement)dragElement).ActualWidth / 2; DropPopup.VerticalOffset = ptLeftUp.Y + y - ((FrameworkElement)dragElement).ActualHeight / 2; this.DropPopup.IsOpen = true; } #endregion } /// /// 当前项数据Model /// public class ListBoxDataModel : ObservableObject { private ObservableCollection _ViewItems; public ObservableCollection ViewItems { get { return _ViewItems; } set { _ViewItems = value; OnPropertyChanged("ViewItems"); } } public ListBoxDataModel() { ViewItems = new ObservableCollection(); } } /// /// 行数据Model /// public class ItemModel : ObservableObject { private string _Name; public string Name { get { return _Name; } set { _Name = value; OnPropertyChanged("Name"); } } private string _Ph; public string Ph { get { return _Ph; } set { _Ph = value; OnPropertyChanged("Ph"); } } } /// /// 帮助类 /// internal static class Utils { /// /// 根据子元素查找父元素 /// /// /// /// public static T FindVisualParent(DependencyObject obj) where T : class { while (obj != null) { if (obj is T) return obj as T; obj = VisualTreeHelper.GetParent(obj); } return null; } /// /// 查询子控件 /// /// /// /// public static IEnumerable FindVisualChildren(DependencyObject depObj) where T : DependencyObject { if (depObj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { DependencyObject child = VisualTreeHelper.GetChild(depObj, i); if (child != null && child is T) { yield return (T)child; } foreach (T childOfChild in FindVisualChildren(child)) { yield return childOfChild; } } } } } }