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
|
{
|
/// <summary>
|
/// WellPlate.xaml 的交互逻辑
|
/// </summary>
|
public partial class WellPlate : UserControl
|
{
|
#region custom event
|
/// <summary>
|
/// 选中列事件,参数为选中的列数
|
/// </summary>
|
public static readonly RoutedEvent SelectedRoutedEvent =
|
EventManager.RegisterRoutedEvent("SelectedEvent", RoutingStrategy.Bubble, typeof(CustomEvent.CustomRoutedEventHandler<string>), typeof(WellPlate));
|
|
[Description("SelectedEvent")]
|
public event CustomEvent.CustomRoutedEventHandler<string> SelectedEvent
|
{
|
add
|
{
|
this.AddHandler(SelectedRoutedEvent, value);
|
}
|
remove
|
{
|
this.RemoveHandler(SelectedRoutedEvent, value);
|
}
|
}
|
|
private void RaiseSelectEvent(string str)
|
{
|
CustomRoutedEventArgs<string> arg = new CustomRoutedEventArgs<string>(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));
|
/// <summary>
|
/// 选择方向 0:水平方向 1:垂直方向
|
/// </summary>
|
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));
|
/// <summary>
|
/// 选择模式 1:单个孔 8:1列
|
/// </summary>
|
public int SelectType
|
{
|
get { return (int)GetValue(SelectTypeProperty); }
|
set { SetValue(SelectTypeProperty, value); }
|
}
|
|
/// <summary>
|
/// 行数
|
/// </summary>
|
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); }
|
}
|
|
/// <summary>
|
/// 列数
|
/// </summary>
|
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(WellPlate),
|
new FrameworkPropertyMetadata((int)12, OnCountChanged));
|
|
public static ObservableCollection<LabwareWellInfo> labwareWellInfoListLocal = null;
|
/// <summary>
|
/// 耗材的孔位数据
|
/// </summary>
|
public ObservableCollection<LabwareWellInfo> labwareWellInfoList
|
{
|
get { return (ObservableCollection<LabwareWellInfo>)GetValue(LabwareWellInfoProperty); }
|
set { SetValue(LabwareWellInfoProperty, value); }
|
}
|
public static readonly DependencyProperty LabwareWellInfoProperty =
|
DependencyProperty.Register("labwareWellInfoListPlane", typeof(ObservableCollection<LabwareWellInfo>), typeof(WellPlate), new PropertyMetadata(null));
|
|
public static double LabwareRealLengthLocal = 0d;
|
/// <summary>
|
/// 耗材的实际长
|
/// </summary>
|
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;
|
/// <summary>
|
/// 耗材的实际宽
|
/// </summary>
|
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));
|
/// <summary>
|
/// 选择内容
|
/// </summary>
|
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<string> list = new List<string>();
|
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<int> listCol = new List<int>();
|
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);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 增加管架孔圈
|
/// </summary>
|
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);
|
}
|
}
|
}
|