using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using POSV.MessageEvent; using POSV.Utils; using POSV.Bean; using POSV.Entity; using DevComponents.DotNetBar.Metro; using DevComponents.DotNetBar; using System.Runtime.InteropServices; using System.Threading; using POSV.Entity.Stock; namespace POSV.Component { [ToolboxItem(true)] public partial class ProductSelectControl : BaseUserControl { /// /// 数据源 /// private List _dataSource = null; /// /// 键盘、方向键、搜索操作标识 /// private KeyboardAction _action = KeyboardAction.None; /// /// 当前焦点索引 /// private int _index = 0; /// /// 当前焦点单品 /// private MetroTileItem _curr = null; public ProductSelectControl() { InitializeComponent(); this.BackColor = Color.Transparent; //单品键盘通知事件 MsgEvent.Receive(Constant.PRODUCTSELECT_KEYBOARD_NOTIFY, this.ProductKeyboardEventNotify); } protected void ProductKeyboardEventNotify(object sender , MsgEventArgs args) { if (args != null && args.Data != null) { Enum.TryParse(args.Data.ToString() , out this._action); switch (this._action) { case KeyboardAction.Left: { if (this.itemPanel.Items.Count > 0) { var container = this.itemPanel.Items[0] as ItemContainer; int subItems = container.SubItems.Count; //只有一个单品 if(subItems == 1) { //当前操作的 this._index = 0; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } if (this._index - 1 >= 0) { //当前操作的,重置样式 var focus = container.SubItems[this._index] as MetroTileItem; this.ResetMetroTileItemStyle(focus); //当前操作的 this._index = this._index - 1; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } } } break; case KeyboardAction.Right: { if (this.itemPanel.Items.Count > 0) { var container = this.itemPanel.Items[0] as ItemContainer; int subItems = container.SubItems.Count; //只有一个单品 if (subItems == 1) { //当前操作的 this._index = 0; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } if (this._index + 1 < subItems) { //重置当前样式 var focus = container.SubItems[this._index] as MetroTileItem; this.ResetMetroTileItemStyle(focus); //当前操作的 this._index = this._index + 1; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } } } break; case KeyboardAction.Up: { if (this.itemPanel.Items.Count > 0) { var container = this.itemPanel.Items[0] as ItemContainer; int subItems = container.SubItems.Count; //只有一个单品 if (subItems == 1) { //当前操作的 this._index = 0; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } if (this._index - this.Columns >= 0) { //重置当前样式 var focus = container.SubItems[this._index] as MetroTileItem; this.ResetMetroTileItemStyle(focus); //当前操作的 this._index = this._index - this.Columns; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } } } break; case KeyboardAction.Down: { if (this.itemPanel.Items.Count > 0) { var container = this.itemPanel.Items[0] as ItemContainer; int subItems = container.SubItems.Count; //只有一个单品 if (subItems == 1) { //当前操作的 this._index = 0; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } if (this._index + this.Columns < subItems) { //重置当前样式 var focus = container.SubItems[this._index] as MetroTileItem; this.ResetMetroTileItemStyle(focus); //当前操作的 this._index = this._index + Columns; this._curr = container.SubItems[this._index] as MetroTileItem; this.UpdateSelectedStyle(this._curr); } } } break; case KeyboardAction.Search: { if (this.itemPanel.Items.Count > 0) { var container = this.itemPanel.Items[0] as ItemContainer; if(container.SubItems.Count > 0) { this._index = 0; this._curr = container.SubItems[this._index] as MetroTileItem; //this.UpdateSelectedStyle(this._curr); } LOGGER.Info(">>>>>*****>>>>>{0}" , this._curr != null ? this._curr.Text : "&&&&&"); } } break; case KeyboardAction.Enter: { LOGGER.Info(">>>>>*****>>>>>Enter>>>>{0}" , this._curr == null ? "" : this._curr.Name); if (this._curr != null) { var r = this.RectangleToScreen(this._curr.DisplayRectangle); int dx = (r.Left + this._curr.TileSize.Width / 2); int dy = (r.Top + this._curr.TileSize.Height / 2); var e = new MouseEventArgs(MouseButtons.Left , 1 , dx , dy , 0); SetCursorPos(dx, dy); LOGGER.Info(">>>>>*****>>>>>{0},{1}" , dx,dy); this.OnItemMouseDown(this._curr , e); } } break; } } } [DllImport("User32.dll")] private static extern bool SetCursorPos(int x , int y); public void UpdateSelectedStyle(MetroTileItem item) { item.TileStyle.Font = this.GetSystemFont(this.SelProductFont); item.TileStyle.TextColor = ColorTranslator.FromHtml(this.SelTextColor); item.TitleTextColor = ColorTranslator.FromHtml(this.SelTextColor); item.TileStyle.BackColor = ColorTranslator.FromHtml(this.SelBackColor); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.SelBackColor); item.TileStyle.BorderColor = ColorTranslator.FromHtml(this.SelBackColor); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml(this.SelBackColor); } public void ResetMetroTileItemStyle(MetroTileItem item) { var entity = item.Tag as ProductExt; switch (entity.Name) { case Constant.PREV_PAGER: { item.TileStyle.BackColor = ColorTranslator.FromHtml(this.PagerColor1); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.PagerColor2); //item.TileStyle.BorderColor = ColorTranslator.FromHtml(this.PagerColor1); //item.TileStyle.BorderColor2 = ColorTranslator.FromHtml(this.PagerColor2); } break; case Constant.NEXT_PAGER: { item.TileStyle.BackColor = ColorTranslator.FromHtml(this.PagerColor1); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.PagerColor2); //item.TileStyle.BorderColor = ColorTranslator.FromHtml(this.PagerColor1); //item.TileStyle.BorderColor2 = ColorTranslator.FromHtml(this.PagerColor2); } break; default: { item.TileStyle.Font = this.GetSystemFont(this.FontSize); item.TileStyle.TextColor = ColorTranslator.FromHtml(this.TextColor); item.TitleTextColor = ColorTranslator.FromHtml(this.TextColor); item.TileStyle.BackColor = ColorTranslator.FromHtml(this.BackColor1); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.BackColor2); //item.TileStyle.BorderColor = ColorTranslator.FromHtml(this.BackColor1); //item.TileStyle.BorderColor2 = ColorTranslator.FromHtml(this.BackColor2); } break; } } protected override void OnPaint(PaintEventArgs e) { //base.OnPaint(e); Rectangle rect = new Rectangle(0 , 0 , this.Width , this.Height); ControlPaint.DrawBorder(e.Graphics , rect , Color.Transparent , ButtonBorderStyle.Solid);//画个边框 //ControlPaint.DrawBorder(e.Graphics , rect , // Color.Transparent , 1 , ButtonBorderStyle.Solid , // Color.Transparent , 1 , ButtonBorderStyle.Solid , // Color.Transparent , 1 , ButtonBorderStyle.Solid , // Color.Transparent , 1 , ButtonBorderStyle.Solid //); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.DesignMode) return; var productJsonTemplate = Global.Instance.GlobalConfigStringValue(ConfigConstant.PRODUCT_JSON_TEMPLATE); if (string.IsNullOrEmpty(productJsonTemplate)) { productJsonTemplate = JsonUtils.Serialize(new ProductItem()); } this.RefreshUi(JsonUtils.Deserialize(productJsonTemplate)); //当前页码 this.PageNumber = 1; } public void RefreshUi(ProductItem item) { this.FontSize = item.ProductFont; this.Columns = item.Columns; this.ItemWidth = item.ItemWidth; this.ItemHeight = item.ItemHeight; this.BackColor1 = item.BackColor1; this.BackColor2 = item.BackColor2; this.TextColor = item.TextColor; this.PagerColor1 = item.PagerColor1; this.PagerColor2 = item.PagerColor2; this.ShowType = item.ShowType; this.SaleClearColor = item.SaleClearColor; this.SaleClearFont = item.SaleClearFont; this.SaleClearTextColor = item.SaleClearTextColor; this.SaleStopColor = item.SaleStopColor; this.SaleClearNotifyColor = item.SaleClearNotifyColor; this.SelBackColor = item.SelBackColor; this.SelTextColor = item.SelTextColor; this.SelProductFont = item.SelProductFont; this.ProductCornerType = item.ProductCornerType; UpdateTemplate(); } private void UpdateTemplate() { } private MetroTileItem GetItemTemplate() { MetroTileItem template = new MetroTileItem(); template.TileStyle.PaddingLeft = template.TileStyle.PaddingRight = -2; template.EnableMarkup = true; template.OptionGroup = "Dish"; template.TileStyle.Font = this.itemPanel.Font; template.TileStyle.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; template.TileStyle.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; template.TitleTextAlignment = System.Drawing.ContentAlignment.BottomCenter; template.TileStyle.TextColor = ColorTranslator.FromHtml(this.TextColor); template.TitleTextColor = ColorTranslator.FromHtml(this.TextColor); template.TileStyle.BackColor = ColorTranslator.FromHtml(this.BackColor1); template.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.BackColor1); template.TileStyle.BorderColor = Color.Transparent; //ColorTranslator.FromHtml(this.BackColor1); template.TileStyle.BorderColor2 = Color.Transparent;// ColorTranslator.FromHtml(this.BackColor1); template.TileStyle.BorderWidth = 1; template.TileStyle.CornerDiameter = 8; switch (this.ProductCornerType) { case CornerType.默认: { template.TileStyle.CornerType = eCornerType.Square; } break; case CornerType.圆角: { template.TileStyle.CornerType = eCornerType.Rounded; template.TileStyle.BorderColor = ColorTranslator.FromHtml(this.BackColor1); template.TileStyle.BorderColor2 = ColorTranslator.FromHtml(this.BackColor1); } break; case CornerType.棱角: { template.TileStyle.CornerType = eCornerType.Diagonal; } break; } //显示大小 template.TileSize = new Size(this.ItemWidth , this.ItemHeight); template.MouseDown += OnItemMouseDown; return template; } private void OnItemMouseDown(object sender , MouseEventArgs e) { if(e.Button == MouseButtons.Left) { MetroTileItem item = (MetroTileItem)sender; var product = item.Tag as FoodMaterialDetailEntity; switch (product.ProductName) { case Constant.PREV_PAGER: { int pageNumber = 1; int.TryParse(product.Memo,out pageNumber); this.PageNumber = pageNumber; this.BindDataSource(this._dataSource); } break; case Constant.NEXT_PAGER: { int pageNumber = 1; int.TryParse(product.Memo , out pageNumber); this.PageNumber = pageNumber; this.BindDataSource(this._dataSource); } break; default: { //已选中,特殊颜色选中 item.TileStyle.BackColor = Color.Maroon; item.TileStyle.BackColor2 = Color.Maroon; this.OnProductCheckedChanged(new FoodMaterialEventArgs(product)); } break; } } } public event FoodMaterialEventHandler FoodMaterialCheckedChanged; protected virtual void OnProductCheckedChanged(FoodMaterialEventArgs e) { FoodMaterialCheckedChanged?.Invoke(this , e); } public void BindDataSource(List dataSource, KeyboardAction action = KeyboardAction.None) { this._dataSource = dataSource; this._action = action; this._index = 0; this._curr = null; LOGGER.Trace("单品绑定操作<{0},{1}>" , this._action.ToString() , this._dataSource.Count); if (this._dataSource == null) { this._dataSource = new List(); } if(this.SelectedIds == null) { this.SelectedIds = new List(); } //总数量 this.TotalCount = dataSource.Count; //每页的显示数量 this.PageSize = this.Rows * this.Columns; //清空历史数据 this.itemPanel.Items.Clear(); this.itemPanel.Font = this.GetSystemFont(this._fontSize); //复制新的数据源,进行分页运算 var merge = ProductSelectMerge.Merge(this.Rows , this.Columns , dataSource); var pager = ListPager(merge); ItemContainer ic = new ItemContainer(); ic.MultiLine = true; ic.ItemSpacing = 0; ic.LayoutOrientation = eOrientation.Horizontal; foreach (FoodMaterialDetailEntity entity in pager) { MetroTileItem item = this.GetItemTemplate(); item.Name = entity.SpecId; item.Checked = false; //绑定品类ID到Tag属性 item.Tag = entity; switch (entity.ProductName) { case Constant.PREV_PAGER: { item.Image = POSV.Properties.Resources.left; item.ImageTextAlignment = System.Drawing.ContentAlignment.MiddleCenter; item.TileStyle.BackColor = ColorTranslator.FromHtml(this.PagerColor1); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.PagerColor2); //item.TileStyle.BorderColor = Color.Transparent; //item.TileStyle.BorderColor2 = Color.Transparent; } break; case Constant.NEXT_PAGER: { item.Image = POSV.Properties.Resources.right; item.ImageTextAlignment = System.Drawing.ContentAlignment.MiddleCenter; item.TileStyle.BackColor = ColorTranslator.FromHtml(this.PagerColor1); item.TileStyle.BackColor2 = ColorTranslator.FromHtml(this.PagerColor2); //item.TileStyle.BorderColor = Color.Transparent; //item.TileStyle.BorderColor2 = Color.Transparent; } break; default: { //绑定品类售价 item.TitleText = entity.PackUnitName; //绑定品类名称 //item.Text = string.Format("{0} {1}", entity.ProductNo, entity.ProductName); item.Text = string.Format("{0}", entity.ProductName); if (!string.IsNullOrEmpty(entity.SpecName)) { item.Text += "[" + entity.SpecName + "]"; } if (this.SelectedIds.Contains(entity.SpecId)) { //已选中,特殊颜色选中 item.TileStyle.BackColor = Color.Maroon; item.TileStyle.BackColor2 = Color.Maroon; } } break; } ic.SubItems.Add(item); } this.itemPanel.Items.Add(ic); this.itemPanel.Invalidate(); } /// /// 分页List数据 /// /// /// public List ListPager(List data) { var result = new List(); result.AddRange(data.Skip((this.PageNumber - 1) * this.PageSize).Take(this.PageSize)); return result; } private ProductShowType _showType = ProductShowType.全称和零售价; public ProductShowType ShowType { get { return this._showType; } set { this._showType = value; } } private int _itemHeight = 70; /// ///品类显示的高度 /// public int ItemHeight { get { return _itemHeight; } set { _itemHeight = (value <= 0 ? 70 : value); } } private int _itemWidth = 90; /// /// 品类的宽度 /// public int ItemWidth { get { return this._itemWidth; } set { if (value <= 0) { this._itemWidth = this.ContentWidth / this._columns; } else { this._itemWidth = value; } } } private SystemFont _fontSize = SystemFont.默认; /// /// 字体大小 /// public SystemFont FontSize { get { return this._fontSize; } set { this._fontSize = value; } } private string _backColor1 = ColorTranslator.ToHtml(Color.DimGray); /// /// 品类显示颜色 /// public string BackColor1 { get { return this._backColor1; } set { this._backColor1 = value; } } private string _backColor2 = ColorTranslator.ToHtml(Color.DimGray); /// /// 品类显示颜色 /// public string BackColor2 { get { return this._backColor2; } set { this._backColor2 = value; } } private string _textColor = ColorTranslator.ToHtml(Color.White); /// /// 品类显示颜色 /// public string TextColor { get { return this._textColor; } set { this._textColor = value; } } /// /// 有效区域的宽度,不包含左右分页宽度 /// public int ContentWidth => this.Width /*- this.PagerWidth - (this.Columns + 1)*/; public int ContentHeight => this.Height; private string _pagerColor1 = ColorTranslator.ToHtml(Color.DimGray); /// /// 分页按钮的颜色 /// public string PagerColor1 { get { return this._pagerColor1; } set { this._pagerColor1 = value; } } private string _pagerColor2 = ColorTranslator.ToHtml(Color.DimGray); /// /// 分页按钮的颜色 /// public string PagerColor2 { get { return this._pagerColor2; } set { this._pagerColor2 = value; } } private bool _autoPager = true; /// /// 是否自动隐藏分页 /// public bool AutoPager { get { return this._autoPager; } set { this._autoPager = value; } } /// /// 每页的大小 /// public int PageSize { get; private set; } /// /// 总页数 /// public int PageCount => this.PageSize <= 0 ? 0 : ((this.TotalCount + this.PageSize - 1) / this.PageSize); /// /// 当前页码 /// public int PageNumber { get; set; } /// /// 总数量 /// public int TotalCount { get; private set; } private int _columns = 1; /// /// 每一行显示的数量 /// public int Columns { get { return _columns; } set { _columns = (value <= 0 ? 1 : value); } } /// ///品类默认行数 /// public int Rows => this.Height / this.ItemHeight; //是否有上一页 public bool HasPreviousPage { get { return PageNumber > 1; } } //是否有下一页 public bool HasNextPage { get { return PageNumber < this.PageCount; } } /// /// 沽清品类显示颜色 /// public string SaleClearColor { get; set; } /// /// 沽清品类提醒颜色 /// public string SaleClearNotifyColor { get; set; } /// /// 沽清字体显示颜色 /// public string SaleClearTextColor { get; set; } /// /// 沽清的字体大小 /// public SystemFont SaleClearFont { get; set; } /// /// 沽清停售显示颜色 /// public string SaleStopColor { get; set; } /// /// 选中品项显示颜色 /// public string SelBackColor { get; set; } /// /// 选中字体显示颜色 /// public string SelTextColor { get; set; } /// /// 选中品项的字体 /// public SystemFont SelProductFont { get; set; } /// /// 品项的显示样式 /// public CornerType ProductCornerType { get; set; } = CornerType.圆角; /// /// 选中列表 /// public List SelectedIds { get; set; } } public delegate void FoodMaterialEventHandler(object sender, FoodMaterialEventArgs e); public class FoodMaterialEventArgs : EventArgs { public FoodMaterialDetailEntity Entity; public FoodMaterialEventArgs(FoodMaterialDetailEntity data) { this.Entity = data; } } }