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
|
{
|
/// <summary>
|
/// 按照步骤 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 文件中使用控件。
|
///
|
/// <MyNamespace:TipsChannel/>
|
///
|
/// </summary>
|
public class TipsChannel : Grid
|
{
|
private int mark = 0;//sizechange执行次数
|
public List<int> chs = new List<int>();
|
public event EventHandler SelectedChangedEvent;
|
|
|
static TipsChannel()
|
{
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(TipsChannel), new FrameworkPropertyMetadata(typeof(TipsChannel)));
|
}
|
|
/// <summary>
|
/// 通道数, 目前仅支持8通道
|
/// </summary>
|
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
|
|
///// <summary>
|
///// 选中通道集合
|
///// </summary>
|
//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(""));
|
|
/// <summary>
|
/// 已被选中通道集合
|
/// </summary>
|
public List<int> SelectedChannels
|
{
|
get { return (List<int>)GetValue(SelectedChannelsProperty); }
|
set { SetValue(SelectedChannelsProperty, value);}
|
}
|
public static readonly DependencyProperty SelectedChannelsProperty =
|
DependencyProperty.Register("SelectedChannels", typeof(List<int>), typeof(TipsChannel), new PropertyMetadata(new List<int> (),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 所有通道是否开启选择编辑
|
/// <summary>
|
/// 可编辑
|
/// </summary>
|
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
|
}
|
}
|