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.Entity; using System.Diagnostics; using POSV.Utils; using DevComponents.DotNetBar.Metro; using DevComponents.DotNetBar; using POSV.Component; using POSV.ThirdPartyOrderData; namespace POSV.WeiXin { [ToolboxItem(true)] public partial class WeixinProductX : BaseUserControl { /// /// 商品控件默认宽度 /// public const int PRODUCT_DEFAULT_WIDTH = 104; /// /// 商品控件默认高度 /// public const int PRODUCT_DEFAULT_HEIGHT = 76; /// /// 数据源 /// private List _dataSource = null; //这样可以加快多次创建item速度,否则每次要耗时2毫秒 private Image _defaultImage = global::POSV.Properties.Resources.圆角矩形_2x; /// /// 选中的商品列表 /// public List SelectedProducts { get; private set; } = new List(); /// /// 选中的品类 /// public List SelectedCategorys { get; private set; } = new List(); public WeixinProductX() { InitializeComponent(); this.itemPanel.ResizeItemsToFit = false; this.itemPanel.BackgroundStyle.Class = "MetroTileGroupTitle";//很关键 } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.DesignMode) return; ReCalSize(); this.Resize += OnResize; } private void OnResize(object sender, EventArgs e) { switch (this.FindForm().WindowState) { case FormWindowState.Normal: case FormWindowState.Maximized: { ReCalSize(); } break; } } private void ReCalSize() { //计算能显示的列数 var _width = this.ItemWidth + this.ItemSpace - 1; if (_width != 0) { this.Columns = ((this.Width - this.Padding.Left - this.Padding.Right) / _width); } //根据行数,重新规划高度 var _height = this.ItemHeight + this.ItemSpace - 1; if (_height != 0) { this.Rows = ((this.Height - this.Padding.Top - this.Padding.Bottom) / _height); } this.ItemHeight = (this.Height - this.Padding.Top - this.Padding.Bottom) / this.Rows - this.ItemSpace; BindDataSource(this._dataSource, this.SelectedCategorys); } public void BindDataSource(List dataSource, List selectedCategorys) { try { if (this.SelectedProducts == null) { this.SelectedProducts = new List(); } this.SelectedCategorys = selectedCategorys; if(this.SelectedCategorys == null) { this.SelectedCategorys = new List(); } if (dataSource == null) { dataSource = new List(); } //加入分页,避免污染源数据,新建集合 List list = new List(); if (this.SelectedCategorys.Count > 0) { var searchProductByCategorys = dataSource.FindAll(x => this.SelectedCategorys.Contains(x.categoryId)); list.AddRange(searchProductByCategorys == null ? new List() : searchProductByCategorys); this.SelectedProducts.RemoveAll(x => !this.SelectedCategorys.Contains(x.categoryId)); } else { list.AddRange(dataSource); } this._dataSource = list; //可以考虑更优化的分摊机制?张莹 int deltaX = this.Width - this.Padding.Left - this.Padding.Right - (this.ItemWidth + this.ItemSpace) * this.Columns - this.ItemSpace; int deltaY = this.Height - this.Padding.Top - this.Padding.Bottom - (this.ItemHeight + this.ItemSpace) * this.Rows - this.ItemSpace; this.TotalCount = this._dataSource.Count; this.PageSize = this.Columns * this.Rows; //清空历史数据 this.itemPanel.Items.Clear(); //复制新的数据源,进行分页运算 var merge = WeixinProductXMerge.Merge(this.Rows, this.Columns, this._dataSource, false); var pager = ListPager(merge); ItemContainer mainContainer = new ItemContainer(); mainContainer.Name = "productContainer"; mainContainer.MultiLine = (this.Rows > 1); mainContainer.ItemSpacing = this.ItemSpace; mainContainer.LayoutOrientation = eOrientation.Horizontal; //2020-03-03 张莹 add 按照规格商品显示 for (int i=0;i < pager.Count;i++) { ListProductSpec entity = pager[i]; MetroTileItem item = new MetroTileItem(); item.Name = entity.specId; item.Checked = false; item.TileStyle.PaddingLeft = item.TileStyle.PaddingRight = 0; item.EnableMarkup = true; item.OptionGroup = "product"; item.TileStyle.BorderWidth = 0; //正常情况下的背景颜色 item.TileStyle.BackColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BackColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.CornerDiameter = 12; item.TileStyle.CornerType = eCornerType.Rounded; item.TitleTextAlignment = ContentAlignment.TopCenter; //将宽度进行补偿 int _width = this.ItemWidth + (this.Columns > 0 ? (deltaX / this.Columns) : 0); int _height = this.ItemHeight + deltaY; //显示大小 item.TileSize = new Size(_width, _height); //显示编码后,调整呈现位置 item.TileStyle.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; item.TileStyle.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; item.TitleTextAlignment = System.Drawing.ContentAlignment.BottomCenter; //品名 item.TileStyle.TextColor = ColorTranslator.FromHtml("#444444"); //显示已售罄 item.TitleTextColor = ColorTranslator.FromHtml("#444444"); //是否售罄,0-售罄 decimal stock = 0.0M; decimal.TryParse(string.IsNullOrEmpty(entity.stock) ? "0" : entity.stock, out stock); //绑定商品Tag属性 item.Tag = ObjectUtils.Copy(entity); switch (entity.productName) { case Constant.PREV_PAGER: { item.TileStyle.BackgroundImage = _defaultImage; item.Image = global::POSV.Properties.Resources.上一页_2x; item.ImageTextAlignment = ContentAlignment.MiddleCenter; item.Text = string.Empty; } break; case Constant.NEXT_PAGER: { item.TileStyle.BackgroundImage = _defaultImage; item.Image = global::POSV.Properties.Resources.下一页_2x; item.ImageTextAlignment = ContentAlignment.MiddleCenter; item.Text = string.Empty; } break; default: { //显示编码后,调整呈现位置 if(stock <= 0) { item.TitleText = "已售罄"; } //绑定商品名称+规格名称 string productName = entity.productName; string specName = ""; if (!string.IsNullOrEmpty(entity.specName)) { specName = "\r\n[" + entity.specName + "]"; } item.Text = string.Format("{0}{1}", productName, specName); if (this.SelectedProducts.Exists(x=>x.specId.Equals(entity.specId))) { //选中情况下的背景颜色 item.TileStyle.BackColor = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BackColor2 = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BorderColor = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml("#00C7BA"); //选中后菜品名称的颜色 item.TileStyle.TextColor = ColorTranslator.FromHtml("#FFFFFF"); item.TitleTextColor = ColorTranslator.FromHtml("#FFFFFF"); } else { if (stock <= 0) { //正常情况下的背景颜色 item.TileStyle.BackColor = Color.DimGray; item.TileStyle.BackColor2 = Color.DimGray; item.TileStyle.BorderColor = Color.DimGray; item.TileStyle.BorderColor2 = Color.DimGray; item.TileStyle.TextColor = Color.White; item.TitleTextColor = Color.White; } else { //正常情况下的背景颜色 item.TileStyle.BackColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BackColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.TextColor = ColorTranslator.FromHtml("#444444"); item.TitleTextColor = ColorTranslator.FromHtml("#444444"); } } } break; } item.MouseDown -= OnProductMouseDown; item.MouseDown += OnProductMouseDown; mainContainer.SubItems.Add(item); } this.itemPanel.Items.Insert(0, mainContainer); this.itemPanel.Invalidate(); } catch (Exception ex) { LOGGER.Error(ex, "构建商品控件内容异常"); } } private void OnProductMouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { MetroTileItem item = (MetroTileItem)sender; var spec = item.Tag as ListProductSpec; switch (spec.productName) { case Constant.PREV_PAGER: { this.PageNumber = spec.Pager; this.BindDataSource(this._dataSource, this.SelectedCategorys); } break; case Constant.NEXT_PAGER: { this.PageNumber = spec.Pager; this.BindDataSource(this._dataSource, this.SelectedCategorys); } break; default: { //已经被选中,再次点击取消选中 if (this.SelectedProducts.Exists(x => x.specId.Equals(spec.specId))) { //是否售罄,0-售罄 decimal stock = 0.0M; decimal.TryParse(string.IsNullOrEmpty(spec.stock) ? "0" : spec.stock, out stock); if (stock <= 0) { //正常情况下的背景颜色 item.TileStyle.BackColor = Color.DimGray; item.TileStyle.BackColor2 = Color.DimGray; item.TileStyle.BorderColor = Color.DimGray; item.TileStyle.BorderColor2 = Color.DimGray; item.TileStyle.TextColor = Color.White; item.TitleTextColor = Color.White; } else { //正常情况下的背景颜色 item.TileStyle.BackColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BackColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml("#E7EAF1"); item.TileStyle.TextColor = ColorTranslator.FromHtml("#444444"); item.TitleTextColor = ColorTranslator.FromHtml("#444444"); } this.SelectedProducts.RemoveAll(x=>x.specId.Equals(spec.specId)); } else { //选中情况下的背景颜色 item.TileStyle.BackColor = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BackColor2 = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BorderColor = ColorTranslator.FromHtml("#00C7BA"); item.TileStyle.BorderColor2 = ColorTranslator.FromHtml("#00C7BA"); //选中后菜品名称的颜色 item.TileStyle.TextColor = ColorTranslator.FromHtml("#FFFFFF"); item.TitleTextColor = ColorTranslator.FromHtml("#FFFFFF"); this.SelectedProducts.Add(spec); } } break; } } } public event WeixinProductXEventHandler ProductXClick; protected virtual void OnProductXClick(WeixinProductXEventArgs e) { ProductXClick?.Invoke(this, e); } /// /// 分页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 MetroTileItem _selectedItem = null; public MetroTileItem SelectedItem { get { return this._selectedItem; } private set { this._selectedItem = value; } } /// /// 每页数量 /// public int PageSize { get; private set; } /// /// 总页数 /// public int PageCount => this.PageSize <= 0 ? 0 : ((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); } } private int _rows = 1; /// /// 显示行数 /// public int Rows { get { return _rows; } set { _rows = (value < 0 ? 1 : value); } } public int ItemHeight { get; set; } = PRODUCT_DEFAULT_HEIGHT; public int ItemWidth { get; set; } = PRODUCT_DEFAULT_WIDTH; /// /// 控件间距 /// public int ItemSpace { get; set; } = 2; } public delegate void WeixinProductXEventHandler(object sender, WeixinProductXEventArgs e); public class WeixinProductXEventArgs : EventArgs { public ListProductSpec Product; public WeixinProductXEventArgs(ListProductSpec data) { this.Product = data; } } public class WeixinProductXMerge { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); public static List Merge(int rows, int cols, List dataSource, bool touchEnabled) { Stopwatch sw = Stopwatch.StartNew(); //启用触摸屏,不分页 if (touchEnabled) { return dataSource; } //移除可能存在的分页标识 dataSource.RemoveAll(x => Constant.PREV_PAGER.Equals(x.productName) || Constant.NEXT_PAGER.Equals(x.productName)); int pageSize = rows * cols; int totalCount = dataSource.Count; //启用分页 int pageCount = ((totalCount - 1) + (pageSize - 2) - 1) / (pageSize - 2); if (pageCount > 1) { int offset = 0; for (int page = 1; page <= pageCount; page++) { if (page == 1) { offset = page * pageSize - 1; var entity = new ListProductSpec(); entity.id = IdWorkerUtils.Instance.NextId(); entity.productName = Constant.NEXT_PAGER; entity.Pager = (page + 1); dataSource.Insert(offset, entity); } else if (page < pageCount) { offset = page * pageSize - 2; var entity = new ListProductSpec(); entity.id = IdWorkerUtils.Instance.NextId(); entity.productName = Constant.PREV_PAGER; entity.Pager = (page - 1); dataSource.Insert(offset, entity); offset++; entity = new ListProductSpec(); entity.id = IdWorkerUtils.Instance.NextId(); entity.productName = Constant.NEXT_PAGER; entity.Pager = (page + 1); dataSource.Insert(offset, entity); } else { var entity = new ListProductSpec(); entity.id = IdWorkerUtils.Instance.NextId(); entity.productName = Constant.PREV_PAGER; entity.Pager = (page - 1); dataSource.Add(entity); } } } logger.Info("小程序商品控件插入分页控件,耗时<{0}>", sw.ElapsedMilliseconds); return dataSource; } } }