using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using XHandler.Class;
using XHandler.Class.DataEx;
using XImagingXhandler.XDAL;
namespace XHandler.Controls
{
///
/// WellPlate.xaml 的交互逻辑
///
public partial class WellPlate : UserControl
{
#region custom event
///
/// 选中列事件,参数为选中的列数
///
public static readonly RoutedEvent SelectedRoutedEvent =
EventManager.RegisterRoutedEvent("SelectedEvent", RoutingStrategy.Bubble, typeof(CustomEvent.CustomRoutedEventHandler), typeof(WellPlate));
[Description("SelectedEvent")]
public event CustomEvent.CustomRoutedEventHandler SelectedEvent
{
add
{
this.AddHandler(SelectedRoutedEvent, value);
}
remove
{
this.RemoveHandler(SelectedRoutedEvent, value);
}
}
private void RaiseSelectEvent(string str)
{
CustomRoutedEventArgs arg = new CustomRoutedEventArgs(SelectedRoutedEvent, str);
this.RaiseEvent(arg);
}
#endregion
public static readonly DependencyProperty SelectOrientationProperty = DependencyProperty.Register("SelectOrientation", typeof(int), typeof(WellPlate),
new FrameworkPropertyMetadata((int)1, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(SelectOrientationChanged), null));
///
/// 选择方向 0:水平方向 1:垂直方向
///
public int SelectOrientation
{
get { return (int)GetValue(SelectOrientationProperty); }
set { SetValue(SelectOrientationProperty, value); }
}
private static void SelectOrientationChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
WellPlate plate = sender as WellPlate;
}
public static readonly DependencyProperty SelectTypeProperty = DependencyProperty.Register("SelectType", typeof(int), typeof(WellPlate),
new FrameworkPropertyMetadata((int)1, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(SelectOrientationChanged), null));
///
/// 选择模式 1:单个孔 8:1列
///
public int SelectType
{
get { return (int)GetValue(SelectTypeProperty); }
set { SetValue(SelectTypeProperty, value); }
}
///
/// 行数
///
public static readonly DependencyProperty RowsProperty = DependencyProperty.Register("Rows", typeof(int), typeof(WellPlate),
new FrameworkPropertyMetadata((int)8));
public int Rows
{
get { return (int)GetValue(RowsProperty); }
set { SetValue(RowsProperty, value); }
}
///
/// 列数
///
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(WellPlate),
new FrameworkPropertyMetadata((int)12, OnCountChanged));
public static ObservableCollection labwareWellInfoListLocal = null;
///
/// 耗材的孔位数据
///
public ObservableCollection labwareWellInfoList
{
get { return (ObservableCollection)GetValue(LabwareWellInfoProperty); }
set { SetValue(LabwareWellInfoProperty, value); }
}
public static readonly DependencyProperty LabwareWellInfoProperty =
DependencyProperty.Register("labwareWellInfoListPlane", typeof(ObservableCollection), typeof(WellPlate), new PropertyMetadata(null));
public static double LabwareRealLengthLocal = 0d;
///
/// 耗材的实际长
///
public double LabwareRealLength
{
get { return (double)GetValue(LabwareRealLengthProperty); }
set { SetValue(LabwareRealLengthProperty, value); }
}
public static readonly DependencyProperty LabwareRealLengthProperty =
DependencyProperty.Register("LabwareRealLengthPlane", typeof(double), typeof(WellPlate), new PropertyMetadata(Double.NaN, null));
public static double LabwareRealWidthLocal = 0d;
///
/// 耗材的实际宽
///
public double LabwareRealWidth
{
get { return (double)GetValue(LabwareRealWidthProperty); }
set { SetValue(LabwareRealWidthProperty, value); }
}
public static readonly DependencyProperty LabwareRealWidthProperty =
DependencyProperty.Register("LabwareRealWidthPlane", typeof(double), typeof(WellPlate), new PropertyMetadata(Double.NaN, null));
public int Columns
{
get { return (int)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public static void OnCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
WellPlate plate = (WellPlate)d;
Debug.WriteLine("rows=" + plate.Rows.ToString() + ", columns=" + plate.Columns.ToString());
//plate.SetData();
//plate.labwareWellInfoList = labwareWellInfoListLocal;
//plate.LabwareRealLength = LabwareRealLengthLocal;
//plate.LabwareRealWidth = LabwareRealWidthLocal;
plate.AddWellsCircle();
}
private void SetData()
{
//labwareWellInfoListLocal=labwareWellInfoList;
//LabwareRealLengthLocal= LabwareRealLength;
//LabwareRealWidthLocal = LabwareRealWidth;
}
public static readonly DependencyProperty SelectionProperty = DependencyProperty.Register("Selection", typeof(string), typeof(WellPlate),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnSelectionChanged), null));
///
/// 选择内容
///
public string Selection
{
get { return (string)GetValue(SelectionProperty); }
set { SetValue(SelectionProperty, value); }
}
private static void OnSelectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
WellPlate plate = sender as WellPlate;
string str = (string)e.NewValue;
plate.SetSelection(str);
}
private List list = new List();
private Point startPoint;
public WellPlate()
{
InitializeComponent();
}
private void idGrid_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point curPos = e.GetPosition(idGrid);
if ((Math.Abs(curPos.X - startPoint.X) > SystemParameters.MinimumHorizontalDragDistance)
|| (Math.Abs(curPos.Y - startPoint.Y) > SystemParameters.MinimumVerticalDragDistance))
{
Rect rect = GetCorrectRect(startPoint, curPos);
List listCol = new List();
foreach (var child in idGrid.Children)
{
if (child is Rectangle)
{
Rectangle rectangle = (Rectangle)child;
GeneralTransform generalTransform1 = rectangle.TransformToAncestor(idGrid);
Point currentPoint = generalTransform1.Transform(new Point(0, 0));
Rect childRect = new Rect(currentPoint.X, currentPoint.Y, rectangle.ActualWidth, rectangle.ActualHeight);
if (SelectType == 1)
{
if (childRect.IntersectsWith(rect))
{
rectangle.Fill = FindResource("blueBrush") as SolidColorBrush;
if (!isExistWellName(Selection, rectangle.Name))
{
if (Selection == "")
{
Selection += rectangle.Name;
}
else
{
if (isExistWellName(Selection, rectangle.Name))
{
}
else
{
Selection += "," + rectangle.Name;
}
}
}
}
else
{
rectangle.Fill = Brushes.White;
if (isExistWellName(Selection, rectangle.Name))
{
Selection = dealWellNames(Selection, rectangle.Name);
}
}
}
else if (SelectType == 8)
{
if (childRect.IntersectsWith(rect))
{
int col = Grid.GetColumn(rectangle);
listCol.Add(col);
for (int i = 0; i < Rows; i++)
{
int index = col * Rows + i;
Rectangle rt = idGrid.Children[index] as Rectangle;
rt.Fill = FindResource("blueBrush") as SolidColorBrush;
if (!isExistWellName(Selection, rt.Name))
{
if (Selection == "")
{
Selection += rectangle.Name;
}
else
{
if (isExistWellName(Selection, rectangle.Name))
{
}
else
{
Selection += "," + rectangle.Name;
}
}
}
}
}
else
{
int col = Grid.GetColumn(rectangle);
if (listCol.Contains(col))
continue;
rectangle.Fill = Brushes.White;
if (isExistWellName(Selection, rectangle.Name))
{
Selection = dealWellNames(Selection, rectangle.Name);
}
}
}
}
}
}
}
}
private string ChangePosToString(int row, int col)
{
string ret = "";
char ch = (char)('A' + row);
string strRow = ch.ToString();
ret = strRow + (col + 1).ToString();
return ret;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
this.MouseLeave += WellPlate_MouseLeave;
idGrid.MouseLeave += idGrid_MouseLeave;
idGrid.DataContextChanged += IdGrid_DataContextChanged;
AddWellsCircle();
SetSelection(Selection);
}
private void IdGrid_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
idGrid.ColumnDefinitions.Clear();
idGrid.RowDefinitions.Clear();
idGrid.Children.Clear();
AddWellsCircle();
}
private void idGrid_MouseDown(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}
private void WellPlate_MouseLeave(object sender, MouseEventArgs e)
{
}
private void idGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(idGrid);
HitTestResult result = VisualTreeHelper.HitTest(idGrid, startPoint);
if (result.VisualHit is Rectangle)
{
var a = (Rectangle)result.VisualHit;
ResetSelection(a);
}
}
private void ResetSelection(Rectangle e)
{
foreach (var child in idGrid.Children)
{
if (child is Rectangle)
{
Rectangle ellipse = (Rectangle)child;
//判断是什么
if (ellipse.Tag == e.Tag)//当前选中的看看是否已选中,如果选中则变为不选中,如果不选中则变为选中
{
if (isExistWellName(Selection, (string)e.Tag))
{
ellipse.Fill = Brushes.White;
Selection = dealWellNames(Selection, (string)e.Tag);
}
else
{
ellipse.Fill = FindResource("blueBrush") as SolidColorBrush;
if (string.IsNullOrEmpty(Selection))
{
Selection += ((string)e.Tag);
}
else
{
Selection += "," + ((string)e.Tag);
}
}
}
}
}
}
private string dealWellNames(string wells, string delWell)
{
string strResult = string.Empty;
if (String.IsNullOrEmpty(wells))
{
return strResult;
}
string[] strWells = wells.Split(',');
for (int i = 0; i < strWells.Length; i++)
{
if (strWells[i] != delWell)
{
strResult += strWells[i] + ",";
}
}
if (!string.IsNullOrEmpty(strResult))
{
strResult = strResult.Substring(0, strResult.Length - 1);
}
return strResult;
}
private bool isExistWellName(string wells, string tarWell)
{
if (String.IsNullOrEmpty(wells))
{
return false;
}
bool Result = false;
string[] strWells = wells.Split(',');
for (int i = 0; i < strWells.Length; i++)
{
if (strWells[i] == tarWell)
{
Result = true;
}
}
return Result;
}
private void idGrid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//string str = "";
//foreach(Rectangle rect in idGrid.Children)
//{
// if(list.Contains(rect.Name))
// {
// if (string.IsNullOrEmpty(str))
// str = rect.Name;
// else
// str += "," + rect.Name;
// }
//}
//if (Selection == "")
//{
// Selection += str;
//}
//else
//{
// if (isExistWellName(Selection, str))
// {
// }
// else
// {
// Selection += "," + str;
// }
//}
}
private void idGrid_MouseLeave(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
//string str = "";
//foreach (Rectangle rect in idGrid.Children)
//{
// if (list.Contains(rect.Name))
// {
// if (string.IsNullOrEmpty(str))
// str = rect.Name;
// else
// str += "," + rect.Name;
// }
//}
//if (Selection == "")
//{
// Selection += str;
//}
//else
//{
// if (isExistWellName(Selection,str))
// {
// }
// else
// {
// Selection += "," + str;
// }
//}
}
}
private void UpdatePlate()
{
try
{
if (idGrid.Children.Count == 0)
return;
int count = Rows * Columns;
for (int i = 0; i < count; i++)
{
Rectangle rect = idGrid.Children[i] as Rectangle;
if (list.Contains(rect.Name))
rect.Fill = FindResource("blueBrush") as SolidColorBrush;
else
rect.Fill = Brushes.White;
}
}
catch (Exception ex)
{
}
}
public string GetSelected(int col)
{
string ret = "";
for (int i = 0; i < Rows; i++)
{
char ch = (char)('A' + i);
if (string.IsNullOrEmpty(ret))
ret = ch.ToString() + col.ToString();
else
ret += "," + ch.ToString() + col.ToString();
}
return ret;
}
public void CreateWells()
{
topGrid.Children.Clear();
topGrid.ColumnDefinitions.Clear();
leftGrid.Children.Clear();
leftGrid.RowDefinitions.Clear();
idGrid.Children.Clear();
idGrid.RowDefinitions.Clear();
idGrid.ColumnDefinitions.Clear();
//Selection = "";
for (int column = 0; column < Columns; column++)
{
topGrid.ColumnDefinitions.Add(new ColumnDefinition());
TextBlock tb = new TextBlock()
{
Text = (column + 1).ToString(),
Style = FindResource("smallTextStyle1") as Style,
};
topGrid.Children.Add(tb);
Grid.SetColumn(tb, column);
idGrid.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int row = 0; row < Rows; row++)
{
leftGrid.RowDefinitions.Add(new RowDefinition());
char ch = (char)('A' + row);
TextBlock tb = new TextBlock()
{
Text = ch.ToString(),
Style = FindResource("smallTextStyle2") as Style,
};
leftGrid.Children.Add(tb);
Grid.SetRow(tb, row);
idGrid.RowDefinitions.Add(new RowDefinition());
}
for (int column = 0; column < Columns; column++)
{
for (int row = 0; row < Rows; row++)
{
Rectangle rectangle = new Rectangle();
rectangle.Name = ChangePosToString(row, column);
if (Columns > 12)
rectangle.Margin = new Thickness(2, 2, 2, 2);
else
rectangle.Margin = new Thickness(4, 4, 4, 4);
rectangle.Fill = Brushes.White;
rectangle.Stroke = Brushes.Gray;
rectangle.Tag = rectangle.Name;
idGrid.Children.Add(rectangle);
Grid.SetRow(rectangle, row);
Grid.SetColumn(rectangle, column);
}
}
}
///
/// 增加管架孔圈
///
private void AddWellsCircle()
{
//根据labwareName 获取该耗材内部孔位数据
if (labwareWellInfoList != null)
{
//先计算出版面比例
double labwareFaceHeight = idGrid.ActualHeight;
double labwareFaceWidth = idGrid.ActualWidth;
double realHeight = LabwareRealWidth;//LabwareHeight;
double realWidth = LabwareRealLength;//LabwareWidth;
double widthScale = (double)labwareFaceWidth / realWidth;
double heightScale = (double)labwareFaceHeight / realHeight;
if (labwareWellInfoList.Count == 0)
{
CreateWells();
}
else
{
foreach (LabwareWellInfo l in labwareWellInfoList)
{
Ellipse ellipse = new Ellipse();
ellipse.Name = l.labware_well_name;
double diameterVal = l.well_max_length * widthScale;
ellipse.Width = diameterVal;
ellipse.Height = diameterVal;
//ellipse.HorizontalAlignment = HorizontalAlignment.Center;
//ellipse.VerticalAlignment = VerticalAlignment.Center;
ellipse.Stroke = Brushes.Gray;
ellipse.StrokeThickness = 1;
ellipse.Fill = Brushes.White;
double labwareEllipsePixelx = l.labware_well_center_x * widthScale;
double labwareEllipsePixely = l.labware_well_center_y * heightScale;
ellipse.Tag = (labwareEllipsePixelx - diameterVal / (double)2).ToString() + "," + (labwareEllipsePixely - diameterVal / (double)2).ToString();
ellipse.Loaded += Ellipse_Loaded;
idGrid.Children.Add(ellipse);
//ellipse.Margin = new Thickness(20,20, 0, 0);
//Grid.SetColumn(ellipse, i);
//Grid.SetRow(ellipse, j);
//孔位文字
TextBlock textBlock = new TextBlock();
textBlock.Text = l.labware_well_name;
textBlock.Width = diameterVal;
textBlock.Height = diameterVal;
textBlock.Background = Brushes.Transparent;
textBlock.Foreground = Brushes.Black;
textBlock.Tag = (labwareEllipsePixelx - diameterVal / (double)2).ToString() + "," + (labwareEllipsePixely - diameterVal / (double)2).ToString();
textBlock.Loaded += textBlock_Loaded;
idGrid.Children.Add(textBlock);
}
}
}
else
{
CreateWells();
}
}
private void Ellipse_Loaded(object sender, RoutedEventArgs e)
{
Ellipse ellipse = sender as Ellipse;
ellipse.HorizontalAlignment = HorizontalAlignment.Left;
ellipse.VerticalAlignment = VerticalAlignment.Top;
string[] strPixels = Convert.ToString(ellipse.Tag).Split(',');
ellipse.Margin = new Thickness(Convert.ToDouble(strPixels[0]), Convert.ToDouble(strPixels[1]), 0, 0);
}
private void textBlock_Loaded(object sender, RoutedEventArgs e)
{
TextBlock textBlock = sender as TextBlock;
textBlock.HorizontalAlignment = HorizontalAlignment.Left;
textBlock.VerticalAlignment = VerticalAlignment.Top;
string[] strPixels = Convert.ToString(textBlock.Tag).Split(',');
textBlock.Margin = new Thickness(Convert.ToDouble(strPixels[0]), Convert.ToDouble(strPixels[1]), 0, 0);
}
public void SetSelection(string selection)
{
list.Clear();
if (selection == null)
{
return;
}
if (selection.Contains("="))
{
return;
}
string[] ary = selection.Split(',');
foreach (string s in ary)
{
if (string.IsNullOrEmpty(s)) break;
string val = s.Substring(1);
int col = int.Parse(val);
list.Add(s);
}
UpdatePlate();
}
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);
}
}
}