using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace XHandler.Controls
{
///
/// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
///
/// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:XHandler.Controls"
///
///
/// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:XHandler.Controls;assembly=XHandler.Controls"
///
/// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
/// 并重新生成以避免编译错误:
///
/// 在解决方案资源管理器中右击目标项目,然后依次单击
/// “添加引用”->“项目”->[浏览查找并选择此项目]
///
///
/// 步骤 2)
/// 继续操作并在 XAML 文件中使用控件。
///
///
///
///
public class TipsChannel : Grid
{
private int mark = 0;//sizechange执行次数
public List chs = new List();
public event EventHandler SelectedChangedEvent;
static TipsChannel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TipsChannel), new FrameworkPropertyMetadata(typeof(TipsChannel)));
}
///
/// 通道数, 目前仅支持8通道
///
public int TotalChannels
{
get { return (int)GetValue(TotalChannelsProperty); }
set { SetValue(TotalChannelsProperty, value); }
}
public static readonly DependencyProperty TotalChannelsProperty =
DependencyProperty.Register("TotalChannels", typeof(int), typeof(TipsChannel), new PropertyMetadata(0, OnTotalChannelChanged));
#region 仅在第一次初始化界面时,设置界面的通道数目
private static void OnTotalChannelChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
//TipsChannel tipsChannel = sender as TipsChannel;
//int count = (int)e.NewValue;
//tipsChannel.SetTotalChannelCount(count);
}
#endregion
/////
///// 选中通道集合
/////
//public string Selection
//{
// get { return (string)GetValue(SelectionProperty); }
// set { SetValue(SelectionProperty, value); }
//}
//public static readonly DependencyProperty SelectionProperty =
// DependencyProperty.Register("Selection", typeof(string), typeof(TipsChannel), new PropertyMetadata(""));
///
/// 已被选中通道集合
///
public List SelectedChannels
{
get { return (List)GetValue(SelectedChannelsProperty); }
set { SetValue(SelectedChannelsProperty, value);}
}
public static readonly DependencyProperty SelectedChannelsProperty =
DependencyProperty.Register("SelectedChannels", typeof(List), typeof(TipsChannel), new PropertyMetadata(new List (),OnSelectedChanged));
#region 被选择的通道数变化事件
private static void OnSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
TipsChannel tipsChannel = sender as TipsChannel;
tipsChannel.SetSelectedChannels();
}
#endregion
#region 重新设置被选择的通道
public void SetSelectedChannels()
{
foreach (var child in Children)
{
if (child is Ellipse)
{
Ellipse ellipse = (Ellipse)child;
//判断是什么
if (SelectedChannels.Contains((int)ellipse.Tag))
{
ellipse.Fill = FindResource("blueBrush") as SolidColorBrush;
ellipse.Stroke = FindResource("blueBrush") as SolidColorBrush;
}
else
{
ellipse.Fill = Brushes.White;
ellipse.Stroke = new SolidColorBrush(Color.FromRgb(0x61, 0x64, 0x67));
}
}
}
}
#endregion
#region 所有通道是否开启选择编辑
///
/// 可编辑
///
public bool CanEdit
{
get { return (bool)GetValue(CanEditProperty); }
set { SetValue(CanEditProperty, value); }
}
public static readonly DependencyProperty CanEditProperty =
DependencyProperty.Register("CanEdit", typeof(bool), typeof(TipsChannel), new PropertyMetadata(false));
#endregion
Rectangle MouseRect;
Point startPoint;
bool isMouseDown = false;
#region 构造函数
public TipsChannel()
{
InitializeComponent();
}
#endregion
#region 初始化函数
void InitializeComponent()
{
Initialized += TipsChannel_Initialized;
//SizeChanged += TipsChannel_SizeChanged;
PreviewMouseDown += TipsChannel_PreviewMouseDown;
PreviewMouseMove += TipsChannel_PreviewMouseMove;
PreviewMouseUp += TipsChannel_PreviewMouseUp;
MouseLeave += TipsChannel_MouseLeave;
}
#endregion
#region 鼠标离开控件显示区域后,更改鼠标按下状态标志
private void TipsChannel_MouseLeave(object sender, MouseEventArgs e)
{
isMouseDown = false;
}
#endregion
#region 鼠标抬起控件显示区域后,更改鼠标按下状态标志
private void TipsChannel_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
isMouseDown = false;
}
#endregion
#region 鼠标被按下后,在控件内选择通道事件
private void TipsChannel_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (!CanEdit)
return;
if (isMouseDown)
{
Point curPos = e.GetPosition(this);
if ((Math.Abs(curPos.X - startPoint.X) > SystemParameters.MinimumHorizontalDragDistance)
|| (Math.Abs(curPos.Y - startPoint.Y) > SystemParameters.MinimumVerticalDragDistance))
{
Rect rect = GetCorrectRect(startPoint, curPos);
foreach (var child in Children)
{
if (child is Ellipse)
{
Ellipse ellipse = (Ellipse)child;
GeneralTransform generalTransform1 = ellipse.TransformToAncestor(this);
Point currentPoint = generalTransform1.Transform(new Point(0, 0));
Rect childRect = new Rect(currentPoint.X, currentPoint.Y, ellipse.ActualWidth, ellipse.ActualHeight);
if (childRect.IntersectsWith(rect))
{
ellipse.Fill = FindResource("blueBrush") as SolidColorBrush;
ellipse.Stroke = FindResource("blueBrush") as SolidColorBrush;
if (SelectedChannels.Contains((int)ellipse.Tag))
{
}
else
{
SelectedChannels.Add((int)ellipse.Tag);
}
}
}
}
}
}
}
#endregion
#region 获取当前鼠标选中的矩形区域
Rect GetCorrectRect(Point start, Point end)
{
if (end.X < start.X)
{
double tmp = start.X;
start.X = end.X;
end.X = tmp;
}
if (end.Y < start.Y)
{
double tmp = start.Y;
start.Y = end.Y;
end.Y = tmp;
}
return new Rect(start.X, start.Y, end.X - start.X, end.Y - start.Y);
}
#endregion
#region 鼠标按下后事件
private void TipsChannel_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (!CanEdit)
return;
startPoint = e.GetPosition(this);
HitTestResult result = VisualTreeHelper.HitTest(this, startPoint);
if (result.VisualHit is Ellipse)
{
var a = (Ellipse)result.VisualHit;
//if (SelectedChannels.Contains((int)a.Tag))
//{
// SelectedChannels.Remove((int)a.Tag);
//}
//else
//{
// SelectedChannels.Add((int)a.Tag);
//}
isMouseDown = true;
ResetSelection(a);
}
}
#endregion
#region 重新设置当前选中的区域内的通道
private void ResetSelection(Ellipse e)
{
foreach (var child in Children)
{
if (child is Ellipse)
{
Ellipse ellipse = (Ellipse)child;
//判断是什么
if (ellipse.Tag == e.Tag)//当前选中的看看是否已选中,如果选中则变为不选中,如果不选中则变为选中
{
if (SelectedChannels.Contains((int)e.Tag))
{
ellipse.Fill = Brushes.White;
ellipse.Stroke = new SolidColorBrush(Color.FromRgb(0x61, 0x64, 0x67));
SelectedChannels.Remove((int)e.Tag);
}
else
{
ellipse.Fill = FindResource("blueBrush") as SolidColorBrush;
ellipse.Stroke = FindResource("blueBrush") as SolidColorBrush;
SelectedChannels.Add((int)e.Tag);
}
}
//ellipse.Fill = Brushes.White;
//ellipse.Stroke = new SolidColorBrush(Color.FromRgb(0x61, 0x64, 0x67));
}
}
chs = SelectedChannels;
if (SelectedChangedEvent != null)
{
SelectedChangedEvent(this, EventArgs.Empty);
}
}
#endregion
//#region 控件显示外观大小变化事件
//private void TipsChannel_SizeChanged(object sender, SizeChangedEventArgs e)
//{
// if(mark>=1)
// {
// return;
// }
// this.ColumnDefinitions.Clear();
// this.RowDefinitions.Clear();
// this.Children.Clear();
// AddItems();
// mark++;
//}
//#endregion
#region 控件初始化事件, 根据设置的通道总数,构建界面通道显示
private void TipsChannel_Initialized(object sender, EventArgs e)
{
//if (mark >= 1)
//{
// return;
//}
this.ColumnDefinitions.Clear();
this.RowDefinitions.Clear();
this.Children.Clear();
AddItems();
mark++;
}
#endregion
#region 初始化控件内的通道数目
private void AddItems()
{
if (TotalChannels > 8)
TotalChannels = 8;
this.RowDefinitions.Add(new RowDefinition());
this.RowDefinitions.Add(new RowDefinition());
for (int i = 0; i < TotalChannels; i++)
{
this.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int i = 0; i < TotalChannels; i++)
{
Ellipse ellipse = new Ellipse()
{
Margin = new Thickness(4, 2, 4, 2),
Width = 24,
Height = 24,
StrokeThickness = 1,
Fill = FindResource("blueBrush") as SolidColorBrush,
Stroke = FindResource("blueBrush") as SolidColorBrush,
Tag = i + 1
};
this.Children.Add(ellipse);
if (!SelectedChannels.Contains(i + 1))
{
SelectedChannels.Add(i + 1);
}
Grid.SetRow(ellipse, 0);
Grid.SetColumn(ellipse, i);
TextBlock tb = new TextBlock()
{
Text = (i + 1).ToString(),
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center,
};
this.Children.Add(tb);
Grid.SetRow(tb, 1);
Grid.SetColumn(tb, i);
}
}
#endregion
#region 重新构建通道显示
public void ResetChannelItems()
{
SelectedChannels.Clear();
this.ColumnDefinitions.Clear();
this.RowDefinitions.Clear();
this.Children.Clear();
int currentChannelTotal = TotalChannels;//当前通道总数量
this.RowDefinitions.Add(new RowDefinition());
this.RowDefinitions.Add(new RowDefinition());
for (int i = 0; i < currentChannelTotal; i++)
{
this.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int i = 0; i < currentChannelTotal; i++)
{
#region 构建通道示意圆圈
Ellipse ellipse = new Ellipse()
{
Margin = new Thickness(4, 2, 4, 2),
Width = 24,
Height = 24,
StrokeThickness = 1,
Fill = FindResource("blueBrush") as SolidColorBrush,
Stroke = FindResource("blueBrush") as SolidColorBrush,
Tag = i + 1
};
this.Children.Add(ellipse);
if (!SelectedChannels.Contains(i + 1))
{
SelectedChannels.Add(i + 1);
}
Grid.SetRow(ellipse, 0);
Grid.SetColumn(ellipse, i);
#endregion
#region 构建通道编号文字
TextBlock tb = new TextBlock()
{
Text = (i + 1).ToString(),
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center,
};
this.Children.Add(tb);
Grid.SetRow(tb, 1);
Grid.SetColumn(tb, i);
#endregion
}
}
#endregion
#region
public void SetTotalChannelCount(int count)
{
mark = 0;
this.ColumnDefinitions.Clear();
this.RowDefinitions.Clear();
this.Children.Clear();
TotalChannels = count;
AddItems();
chs = SelectedChannels;
}
#endregion
}
}