public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == null) throw new ArgumentNullException("DestinationType cannot be null"); //MessageBox.Show("Convertto OK"); if (destinationType == typeof(InstanceDescriptor) && (value is ChatListItem)) { ConstructorInfo constructor = null; ChatListItem item = (ChatListItem)value; ChatListSubItem[] subItems = null; //MessageBox.Show("Convertto Start Item:" + item.Text); //MessageBox.Show("Item.SubItems.Count:" + item.SubItems.Count); if (item.SubItems.Count > 0) { subItems = new ChatListSubItem[item.SubItems.Count]; item.SubItems.CopyTo(subItems, 0); } //MessageBox.Show("Item.SubItems.Count:" + item.SubItems.Count); if (item.Text != null && subItems != null) constructor = typeof(ChatListItem).GetConstructor(new Type[] { typeof(string), typeof(ChatListSubItem[]) }); //MessageBox.Show("Constructor(Text,item[]):" + (constructor != null)); if (constructor != null) return new InstanceDescriptor(constructor, new object[] { item.Text, subItems }, false); if (subItems != null) constructor = typeof(ChatListItem).GetConstructor(new Type[] { typeof(ChatListSubItem[]) }); if (constructor != null) return new InstanceDescriptor(constructor, new object[] { subItems }, false); if (item.Text != null) { //MessageBox.Show("StartGetConstructor(text)"); constructor = typeof(ChatListItem).GetConstructor(new Type[] { typeof(string), typeof(bool) }); } //MessageBox.Show("Constructor(Text):" + (constructor != null)); if (constructor != null) { //System.Windows.Forms.MessageBox.Show("text OK"); return new InstanceDescriptor(constructor, new object[] { item.Text, item.IsOpen }); } } return base.ConvertTo(context, culture, value, destinationType); }
/// <summary> /// 绘制列表子项 /// </summary> /// <param name="g">绘图表面</param> /// <param name="subItem">要绘制的子项</param> /// <param name="rectSubItem">该子项的区域</param> /// <param name="sb">画刷</param> protected virtual void DrawSubItem(Graphics g, ChatListSubItem subItem, ref Rectangle rectSubItem, SolidBrush sb) { if (subItem.Equals(selectSubItem)) { //判断改子项是否被选中 rectSubItem.Height = (int)ChatListItemIcon.Large; //如果选中则绘制成大图标 sb.Color = this.subItemSelectColor; g.FillRectangle(sb, rectSubItem); //对color进行变换 for (int i = rectSubItem.Height; i > 0; i--) { if (sb.Color.R - i * 3 >= 0//先保证RGB值在合理范围内 && sb.Color.G - i * 3 >= 0) { g.DrawLine(new Pen(Color.FromArgb(100, sb.Color.R - i * 3, sb.Color.G - i * 3, sb.Color.B)), rectSubItem.Left, rectSubItem.Top + i, rectSubItem.Right, rectSubItem.Top + i); } } DrawHeadImage(g, subItem, rectSubItem); //绘制头像 DrawLargeSubItem(g, subItem, rectSubItem); //绘制大图标 显示的个人信息 subItem.Bounds = new Rectangle(rectSubItem.Location, rectSubItem.Size); return; } else if (subItem.Equals(m_mouseOnSubItem)) sb.Color = this.subItemMouseOnColor; else sb.Color = this.subItemColor; g.FillRectangle(sb, rectSubItem);// //对color进行变换 for (int i = rectSubItem.Height; i > 0; i--) { if (sb.Color.R - i * 3 >= 0 && sb.Color.R - i * 3 >= 0) { g.DrawLine(new Pen(Color.FromArgb(100, sb.Color.R - i * 3, sb.Color.G - i * 3, sb.Color.B)), rectSubItem.Left, rectSubItem.Top+i, rectSubItem.Right, rectSubItem.Top+i); } } DrawHeadImage(g, subItem, rectSubItem); if (iconSizeMode == ChatListItemIcon.Large) //没有选中则根据 图标模式绘制 DrawLargeSubItem(g, subItem, rectSubItem); else DrawSmallSubItem(g, subItem, rectSubItem); subItem.Bounds = new Rectangle(rectSubItem.Location, rectSubItem.Size); }
/// <summary> /// 绘制小图标模式的个人信息 /// </summary> /// <param name="g">绘图表面</param> /// <param name="subItem">要绘制信息的子项</param> /// <param name="rectSubItem">该子项的区域</param> protected virtual void DrawSmallSubItem(Graphics g, ChatListSubItem subItem, Rectangle rectSubItem) { rectSubItem.Height = (int)ChatListItemIcon.Small; //重新赋值一个高度 StringFormat sf = new StringFormat(); sf.LineAlignment = StringAlignment.Center; sf.FormatFlags = StringFormatFlags.NoWrap; string strDraw = subItem.DisplayName; if (string.IsNullOrEmpty(strDraw)) strDraw = subItem.NicName; //如果没有备注绘制昵称 Size szFont = TextRenderer.MeasureText(strDraw, this.Font); sf.SetTabStops(0.0F, new float[] { rectSubItem.Height }); g.DrawString("\t" + strDraw, this.Font, Brushes.Black, rectSubItem, sf); sf.SetTabStops(0.0F, new float[] { rectSubItem.Height + 5 + szFont.Width }); g.DrawString("\t" + subItem.PersonalMsg, this.Font, Brushes.Gray, rectSubItem, sf); }
/// <summary> /// 绘制大图标模式的个人信息 /// </summary> /// <param name="g">绘图表面</param> /// <param name="subItem">要绘制信息的子项</param> /// <param name="rectSubItem">该子项的区域</param> protected virtual void DrawLargeSubItem(Graphics g, ChatListSubItem subItem, Rectangle rectSubItem) { rectSubItem.Height = (int)ChatListItemIcon.Large; //重新赋值一个高度 string strDraw = subItem.DisplayName; Size szFont = TextRenderer.MeasureText(strDraw, this.Font); if (szFont.Width > 0) { //判断是否有备注名称 g.DrawString(strDraw, this.Font, Brushes.Black, rectSubItem.Height, rectSubItem.Top + 5); g.DrawString(subItem.NicName, this.Font, Brushes.Gray, rectSubItem.Height + szFont.Width, rectSubItem.Top + 5); } else { //如果没有备注名称 这直接绘制昵称 g.DrawString(subItem.NicName, this.Font, Brushes.Black, rectSubItem.Height, rectSubItem.Top + 5); } //绘制个人签名 g.DrawString(subItem.PersonalMsg, this.Font, Brushes.Gray, rectSubItem.Height, rectSubItem.Top + 5 + this.Font.Height); }
/// <summary> /// 绘制列表子项的头像 /// </summary> /// <param name="g">绘图表面</param> /// <param name="subItem">要绘制头像的子项</param> /// <param name="rectSubItem">该子项的区域</param> protected virtual void DrawHeadImage(Graphics g, ChatListSubItem subItem, Rectangle rectSubItem) { if (subItem.IsTwinkle) { //判断改头像是否闪动 if (subItem.IsTwinkleHide) //同理该值 在线程中 取反赋值 return; } int imageHeight = rectSubItem.Height - 10; //根据子项的大小计算头像的区域 subItem.HeadRect = new Rectangle(5, rectSubItem.Top + 5, imageHeight, imageHeight); if (subItem.HeadImage == null) //如果头像位空 用默认资源给定的头像 subItem.HeadImage = global::_CUSTOM_CONTROLS.Properties.Resources._null; if (subItem.Status == ChatListSubItem.UserStatus.OffLine) g.DrawImage(subItem.GetDarkImage(), subItem.HeadRect); else { pairs_image image = new pairs_image(); g.DrawImage(image.get_image_from_name(subItem.DisplayName), subItem.HeadRect);//绘制小图标 /* if (subItem.Status == ChatListSubItem.UserStatus.QMe) g.DrawImage(global::_CUSTOM_CONTROLS.Properties.Resources.QMe, new Rectangle(subItem.HeadRect.Right - 10, subItem.HeadRect.Bottom - 10, 11, 11)); if (subItem.Status == ChatListSubItem.UserStatus.Away) g.DrawImage(global::_CUSTOM_CONTROLS.Properties.Resources.Away, new Rectangle(subItem.HeadRect.Right - 10, subItem.HeadRect.Bottom - 10, 11, 11)); if (subItem.Status == ChatListSubItem.UserStatus.Busy) g.DrawImage(global::_CUSTOM_CONTROLS.Properties.Resources.Busy, new Rectangle(subItem.HeadRect.Right - 10, subItem.HeadRect.Bottom - 10, 11, 11)); if (subItem.Status == ChatListSubItem.UserStatus.DontDisturb) g.DrawImage(global::_CUSTOM_CONTROLS.Properties.Resources.Dont_Disturb, new Rectangle(subItem.HeadRect.Right - 10, subItem.HeadRect.Bottom - 10, 11, 11)); //*/ } if (subItem.Equals(selectSubItem)) //根据是否选中头像绘制头像的外边框 ;//g.DrawRectangle(Pens.Cyan, subItem.HeadRect); else ;// g.DrawRectangle(Pens.Gray, subItem.HeadRect); }
/// <summary> /// 根据在线状态添加一个子项 /// </summary> /// <param name="subItem">要添加的子项</param> public void AddAccordingToStatus(ChatListSubItem subItem) { if (subItem.Status == ChatListSubItem.UserStatus.OffLine) { this.Add(subItem); return; } for (int i = 0, len = this.count; i < len; i++) { if (subItem.Status <= m_arrSubItems[i].Status) { this.Insert(i, subItem); return; } } this.Add(subItem); }
private void MenuMain_Load(object sender, EventArgs e) { Rectangle rect = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; //Width = rect.Width; Height = rect.Height - 50; this.Location = new Point(10, 40); TitleItem temp_item = new TitleItem(); temp_item.MainTitle = "订单管理"; temp_item.SubItem.Add("订单"); temp_item.SubItem.Add("打样"); temp_item.SubItem.Add("生产"); temp_item.SubItem.Add("出货记录"); temp_item.SubItem.Add("快递记录"); title.Add(temp_item); temp_item = new TitleItem(); temp_item.MainTitle = "任务管理"; temp_item.SubItem.Add("进度跟踪"); temp_item.SubItem.Add("工作日历"); title.Add(temp_item); temp_item = new TitleItem(); temp_item.MainTitle = "物料管理"; temp_item.SubItem.Add("面料"); temp_item.SubItem.Add("辅料"); temp_item.SubItem.Add("特殊工艺"); title.Add(temp_item); temp_item = new TitleItem(); temp_item.MainTitle = "关系管理"; temp_item.SubItem.Add("客户"); temp_item.SubItem.Add("服装厂"); temp_item.SubItem.Add("其他厂商"); temp_item.SubItem.Add("联系人"); title.Add(temp_item); temp_item = new TitleItem(); temp_item.MainTitle = "文件库"; temp_item.SubItem.Add("文件库"); title.Add(temp_item); button1.Text = "闪动"; button2.Text = "插入[离开]"; button3.Text = "大/小图标"; chatListBox1.Items.Clear(); Random rnd = new Random(); for (int i = 0; i < title.Count; i++) { ChatListItem item = new ChatListItem(title[i].MainTitle); for (int j = 0; j < title[i].SubItem.Count; j++) { ChatListSubItem subItem = new ChatListSubItem("", title[i].SubItem[j], "");//注释说明 subItem.HeadImage = getHeadImage(title[i].SubItem[j]); subItem.Status = (ChatListSubItem.UserStatus)(j % 6); item.SubItems.AddAccordingToStatus(subItem); } item.SubItems.Sort(); chatListBox1.Items.Add(item); } ChatListItem itema = new ChatListItem("TEST"); for (int i = 0; i < 5; i++) { chatListBox1.Items.Add(itema); } chatListBox1.Items.Remove(itema); }
private void ClearSubItemMouseOn() { if (m_mouseOnSubItem != null) { this.Invalidate(new Rectangle( m_mouseOnSubItem.Bounds.X, m_mouseOnSubItem.Bounds.Y - chatVScroll.Value, m_mouseOnSubItem.Bounds.Width, m_mouseOnSubItem.Bounds.Height)); m_mouseOnSubItem = null; } }
/// <summary> /// 移除一个子项 /// </summary> /// <param name="subItem">要移除的子项</param> public void Remove(ChatListSubItem subItem) { int index = this.IndexOf(subItem); if (-1 != index) this.RemoveAt(index); }
public ChatListItem(ChatListSubItem[] subItems) { this.subItems.AddRange(subItems); }
/// <summary> /// 根据索引插入一个子项 /// </summary> /// <param name="index">索引位置</param> /// <param name="subItem">要插入的子项</param> public void Insert(int index, ChatListSubItem subItem) { if (index < 0 || index >= this.count) throw new IndexOutOfRangeException("Index was outside the bounds of the array"); if (subItem == null) throw new ArgumentNullException("SubItem cannot be null"); this.EnsureSpace(1); for (int i = this.count; i > index; i--) m_arrSubItems[i] = m_arrSubItems[i - 1]; subItem.OwnerListItem = this.owner; m_arrSubItems[index] = subItem; this.count++; if (this.owner.OwnerChatListBox != null) this.owner.OwnerChatListBox.Invalidate(); }
/// <summary> /// 获取索引位置 /// </summary> /// <param name="subItem">要获取索引的子项</param> /// <returns>索引</returns> public int IndexOf(ChatListSubItem subItem) { return Array.IndexOf<ChatListSubItem>(m_arrSubItems, subItem); }
/// <summary> /// 判断子项是否在集合内 /// </summary> /// <param name="subItem">要判断的子项</param> /// <returns>是否在集合内</returns> public bool Contains(ChatListSubItem subItem) { return this.IndexOf(subItem) != -1; }
/// <summary> /// 添加一组子项 /// </summary> /// <param name="subItems">要添加子项的数组</param> public void AddRange(ChatListSubItem[] subItems) { if (subItems == null) throw new ArgumentNullException("SubItems cannot be null"); this.EnsureSpace(subItems.Length); try { foreach (ChatListSubItem subItem in subItems) { if (subItem == null) throw new ArgumentNullException("SubItem cannot be null"); if (-1 == this.IndexOf(subItem)) { subItem.OwnerListItem = this.owner; m_arrSubItems[this.count++] = subItem; } } } finally { if (this.owner.OwnerChatListBox != null) this.owner.OwnerChatListBox.Invalidate(); } }
protected override void OnClick(EventArgs e) { if (chatVScroll.IsMouseDown) return; //MouseUp事件触发在Click后 滚动条滑块为点下状态 单击无效 if (chatVScroll.ShouldBeDraw) { //如果有滚动条 判断是否在滚动条类点击 if (chatVScroll.Bounds.Contains(m_ptMousePos)) { //判断在滚动条那个位置点击 if (chatVScroll.UpBounds.Contains(m_ptMousePos)) chatVScroll.Value -= 50; else if (chatVScroll.DownBounds.Contains(m_ptMousePos)) chatVScroll.Value += 50; else if (!chatVScroll.SliderBounds.Contains(m_ptMousePos)) chatVScroll.MoveSliderToLocation(m_ptMousePos.Y); return; } }//否则 如果在列表上点击 展开或者关闭 在子项上面点击则选中 foreach (ChatListItem item in items) { if (item.Bounds.Contains(m_ptMousePos)) { if (item.IsOpen) { foreach (ChatListSubItem subItem in item.SubItems) { if (subItem.Bounds.Contains(m_ptMousePos)) { if (subItem.Equals(selectSubItem)) return; selectSubItem = subItem; this.Invalidate(); return; } } if (new Rectangle(0, item.Bounds.Top, this.Width, 20).Contains(m_ptMousePos)) { selectSubItem = null; item.IsOpen = !item.IsOpen; this.Invalidate(); return; } } else { selectSubItem = null; item.IsOpen = !item.IsOpen; this.Invalidate(); return; } } } base.OnClick(e); }
protected override void OnMouseMove(MouseEventArgs e) { m_ptMousePos = e.Location; if (chatVScroll.IsMouseDown) { //如果滚动条的滑块处于被点击 那么移动 chatVScroll.MoveSliderFromLocation(e.Y); return; } if (chatVScroll.ShouldBeDraw) { //如果控件上有滚动条 判断鼠标是否在滚动条区域移动 if (chatVScroll.Bounds.Contains(m_ptMousePos)) { ClearItemMouseOn(); ClearSubItemMouseOn(); if (chatVScroll.SliderBounds.Contains(m_ptMousePos)) chatVScroll.IsMouseOnSlider = true; else chatVScroll.IsMouseOnSlider = false; if (chatVScroll.UpBounds.Contains(m_ptMousePos)) chatVScroll.IsMouseOnUp = true; else chatVScroll.IsMouseOnUp = false; if (chatVScroll.DownBounds.Contains(m_ptMousePos)) chatVScroll.IsMouseOnDown = true; else chatVScroll.IsMouseOnDown = false; return; } else chatVScroll.ClearAllMouseOn(); } m_ptMousePos.Y += chatVScroll.Value; //如果不在滚动条范围类 那么根据滚动条当前值计算虚拟的一个坐标 for (int i = 0, Len = items.Count; i < Len; i++) { //然后判断鼠标是否移动到某一列表项或者子项 if (items[i].Bounds.Contains(m_ptMousePos)) { if (items[i].IsOpen) { //如果展开 判断鼠标是否在某一子项上面 for (int j = 0, lenSubItem = items[i].SubItems.Count; j < lenSubItem; j++) { if (items[i].SubItems[j].Bounds.Contains(m_ptMousePos)) { if (m_mouseOnSubItem != null) { //如果当前鼠标下子项不为空 if (items[i].SubItems[j].HeadRect.Contains(m_ptMousePos)) { //判断鼠标是否在头像内 if (!m_bOnMouseEnterHeaded) { //如果没有触发进入事件 那么触发用户绑定的事件 OnMouseEnterHead(new ChatListEventArgs(this.m_mouseOnSubItem, this.selectSubItem)); m_bOnMouseEnterHeaded = true; } } else { if (m_bOnMouseEnterHeaded) { //如果已经执行过进入事件 那触发用户绑定的离开事件 OnMouseLeaveHead(new ChatListEventArgs(this.m_mouseOnSubItem, this.selectSubItem)); m_bOnMouseEnterHeaded = false; } } } if (items[i].SubItems[j].Equals(m_mouseOnSubItem)) { return; } ClearSubItemMouseOn(); ClearItemMouseOn(); m_mouseOnSubItem = items[i].SubItems[j]; this.Invalidate(new Rectangle( m_mouseOnSubItem.Bounds.X, m_mouseOnSubItem.Bounds.Y - chatVScroll.Value, m_mouseOnSubItem.Bounds.Width, m_mouseOnSubItem.Bounds.Height)); //this.Invalidate(); return; } } ClearSubItemMouseOn(); //循环做完没发现子项 那么判断是否在列表上面 if (new Rectangle(0, items[i].Bounds.Top - chatVScroll.Value, this.Width, 20).Contains(e.Location)) { if (items[i].Equals(m_mouseOnItem)) return; ClearItemMouseOn(); m_mouseOnItem = items[i]; this.Invalidate(new Rectangle( m_mouseOnItem.Bounds.X, m_mouseOnItem.Bounds.Y - chatVScroll.Value, m_mouseOnItem.Bounds.Width, m_mouseOnItem.Bounds.Height)); //this.Invalidate(); return; } } else { //如果列表项没有展开 重绘列表项 if (items[i].Equals(m_mouseOnItem)) return; ClearItemMouseOn(); ClearSubItemMouseOn(); m_mouseOnItem = items[i]; this.Invalidate(new Rectangle( m_mouseOnItem.Bounds.X, m_mouseOnItem.Bounds.Y - chatVScroll.Value, m_mouseOnItem.Bounds.Width, m_mouseOnItem.Bounds.Height)); //this.Invalidate(); return; } } }//若循环结束 既不在列表上也不再子项上 清空上面的颜色 ClearItemMouseOn(); ClearSubItemMouseOn(); base.OnMouseMove(e); }
//确认存储空间 private void EnsureSpace(int elements) { if (m_arrSubItems == null) m_arrSubItems = new ChatListSubItem[Math.Max(elements, 4)]; else if (elements + this.count > m_arrSubItems.Length) { ChatListSubItem[] arrTemp = new ChatListSubItem[Math.Max(m_arrSubItems.Length * 2, elements + this.count)]; m_arrSubItems.CopyTo(arrTemp, 0); m_arrSubItems = arrTemp; } }
public ChatListEventArgs(ChatListSubItem mouseonsubitem, ChatListSubItem selectsubitem) { this.mouseOnSubItem = mouseonsubitem; this.selectSubItem = selectsubitem; }
public ChatListItem(string text, ChatListSubItem[] subItems) { this.text = text; this.subItems.AddRange(subItems); }
public ChatListItem(string text, bool bOpen, ChatListSubItem[] subItems) { this.text = text; this.isOpen = bOpen; this.subItems.AddRange(subItems); }
/// <summary> /// 添加一个子项 /// </summary> /// <param name="subItem">要添加的子项</param> public void Add(ChatListSubItem subItem) { if (subItem == null) throw new ArgumentNullException("SubItem cannot be null"); this.EnsureSpace(1); if (-1 == IndexOf(subItem)) { subItem.OwnerListItem = owner; m_arrSubItems[this.count++] = subItem; if (this.owner.OwnerChatListBox != null) this.owner.OwnerChatListBox.Invalidate(); } }