/// <summary> /// 绘制列表子项 /// </summary> /// <param name="g">绘图表面</param> /// <param name="subItem">要绘制的子项</param> /// <param name="rectSubItem">该子项的区域</param> /// <param name="sb">画刷</param> protected virtual void DrawSongItem(Graphics g, SongItem subItem, ref Rectangle rectSubItem, SolidBrush sb) { if (subItem.Equals(selectSubItem)) //判断改子项是否被选中 { rectSubItem.Height = 55; //如果选中则绘制成大图标 sb.Color = this.subItemSelectColor; g.FillRectangle(sb, rectSubItem); //DrawHeadImage(g, subItem, rectSubItem); //绘制头像 DrawPlayingSongItemm(g, subItem, rectSubItem); //绘制大图标 显示的个人信息 subItem.Bounds = new Rectangle(rectSubItem.Location, rectSubItem.Size); return; } else if (subItem.Equals(MouseOnSongItem)) { sb.Color = this.subItemMouseOnColor; } else { sb.Color = this.subItemColor; } g.FillRectangle(sb, rectSubItem); //DrawHeadImage(g, subItem, rectSubItem); //if (iconSizeMode == IconSize.Large) //没有选中则根据 图标模式绘制 // DrawPlayingSongItemm(g, subItem, rectSubItem); //else DrawNormalSongItem(g, subItem, rectSubItem); subItem.Bounds = new Rectangle(rectSubItem.Location, rectSubItem.Size); }
//实现排序接口 int IComparable.CompareTo(object obj) { if (!(obj is SongItem)) throw new NotImplementedException("obj is not ChatListSubItem"); SongItem subItem = obj as SongItem; return (this.songname).CompareTo(subItem.songname); }
/// <summary> /// 移除一个子项 /// </summary> /// <param name="subItem">要移除的子项</param> public void Remove(SongItem subItem) { int index = this.IndexOf(subItem); if (-1 != index) { this.RemoveAt(index); } }
private void ClearSubItemMouseOn() { if (MouseOnSongItem != null) { this.Invalidate(new Rectangle( MouseOnSongItem.Bounds.X, MouseOnSongItem.Bounds.Y - VScroll.Value, MouseOnSongItem.Bounds.Width, MouseOnSongItem.Bounds.Height)); MouseOnSongItem = null; } }
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 PlayList)) { ConstructorInfo constructor = null; PlayList item = (PlayList)value; SongItem[] subItems = null; //MessageBox.Show("Convertto Start Item:" + item.Text); //MessageBox.Show("Item.SubItems.Count:" + item.SubItems.Count); if (item.SubItems.Count > 0) { subItems = new SongItem[item.SubItems.Count]; item.SubItems.CopyTo(subItems, 0); } //MessageBox.Show("Item.SubItems.Count:" + item.SubItems.Count); if (item.Text != null && subItems != null) { constructor = typeof(PlayList).GetConstructor(new Type[] { typeof(string), typeof(SongItem[]) }); } //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(PlayList).GetConstructor(new Type[] { typeof(SongItem[]) }); } if (constructor != null) { return(new InstanceDescriptor(constructor, new object[] { subItems }, false)); } if (item.Text != null) { //MessageBox.Show("StartGetConstructor(text)"); constructor = typeof(PlayList).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)); }
//确认存储空间 private void EnsureSpace(int elements) { if (m_arrSubItems == null) { m_arrSubItems = new SongItem[Math.Max(elements, 4)]; } else if (elements + this.count > m_arrSubItems.Length) { SongItem[] arrTemp = new SongItem[Math.Max(m_arrSubItems.Length * 2, elements + this.count)]; m_arrSubItems.CopyTo(arrTemp, 0); m_arrSubItems = arrTemp; } }
/// <summary> /// 添加一个子项 /// </summary> /// <param name="subItem">要添加的子项</param> public void Add(SongItem 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.OwnerPlayListBox != null) { this.owner.OwnerPlayListBox.Invalidate(); } } }
/// <summary> /// 绘制正常列表项 /// </summary> /// <param name="g">绘图表面</param> /// <param name="songitem">要绘制信息的子项</param> /// <param name="rectSubItem">该子项的区域</param> protected virtual void DrawNormalSongItem(Graphics g, SongItem songitem, Rectangle rectSubItem) { rectSubItem.Height = 30; //重新赋值一个高度 StringFormat sf = new StringFormat(); sf.LineAlignment = StringAlignment.Center; //sf.Alignment = StringAlignment.Center; sf.FormatFlags = StringFormatFlags.NoWrap; string strDraw = songitem.SongName; 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 }); sf.Alignment = StringAlignment.Far; g.DrawString(string.Format("\t{0:D2}:{1:D2}", +songitem.TotalTime / 60, songitem.TotalTime % 60), this.Font, Brushes.Gray, rectSubItem, sf); }
/// <summary> /// 绘制正在播放的列表项 /// </summary> /// <param name="g">绘图表面</param> /// <param name="songitem">要绘制信息的子项</param> /// <param name="rectSubItem">该子项的区域</param> protected virtual void DrawPlayingSongItemm(Graphics g, SongItem songitem, Rectangle rectSubItem) { g.FillRectangle(new SolidBrush(Color.FromArgb(101, 192, 244)), rectSubItem); rectSubItem.Height = 55; //重新赋值一个高度 StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Near; sf.LineAlignment = StringAlignment.Center; sf.SetTabStops(0.0f, new float[] { 2.0f + rectSubItem.Height + 10 }); Rectangle rectContent = new Rectangle(rectSubItem.X, rectSubItem.Y, rectSubItem.Width, rectSubItem.Height / 2); g.DrawString("\t" + songitem.SongName, this.Font, new SolidBrush(Color.White), rectContent, sf); rectContent.Y += rectSubItem.Height / 2; g.DrawString(string.Format("\t{0:D2}:{1:D2}", songitem.TotalTime / 60, songitem.TotalTime % 60), this.Font, new SolidBrush(Color.White), rectContent, sf); //g.DrawImage(item.HeadImage, item.HeadRect); //item.TailRect = new Rectangle(rectItem.Right - 10 - item.TailButton.Width, rectItem.Top + 2, // item.TailButton.Width, item.TailButton.Height); //g.DrawImage(item.TailButton, item.TailRect); }
/// <summary> /// 根据索引插入一个子项 /// </summary> /// <param name="index">索引位置</param> /// <param name="subItem">要插入的子项</param> public void Insert(int index, SongItem 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.OwnerPlayListBox != null) { this.owner.OwnerPlayListBox.Invalidate(); } }
protected override void OnClick(EventArgs e) { if (VScroll.IsMouseDown) { return; //MouseUp事件触发在Click后 滚动条滑块为点下状态 单击无效 } if (VScroll.ShouldBeDraw) { //如果有滚动条 判断是否在滚动条类点击 if (VScroll.Bounds.Contains(MousePos)) { //判断在滚动条那个位置点击 if (VScroll.UpBounds.Contains(MousePos)) { VScroll.Value -= 50; } else if (VScroll.DownBounds.Contains(MousePos)) { VScroll.Value += 50; } else if (!VScroll.SliderBounds.Contains(MousePos)) { VScroll.MoveSliderToLocation(MousePos.Y); } return; } } //否则 如果在列表上点击 展开或者关闭 在子项上面点击则选中 foreach (PlayList item in items) { if (item.Bounds.Contains(MousePos)) { if (item.IsOpen) { foreach (SongItem songitem in item.SubItems) { if (songitem.Bounds.Contains(MousePos)) { if (songitem.Equals(selectSubItem)) { return; } selectSubItem = songitem; this.Invalidate(); return; } } if (new Rectangle(0, item.Bounds.Top, this.Width, 20).Contains(MousePos)) { 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) { MousePos = e.Location; if (VScroll.IsMouseDown) { //如果滚动条的滑块处于被点击 那么移动 VScroll.MoveSliderFromLocation(e.Y); return; } if (VScroll.ShouldBeDraw) { //如果控件上有滚动条 判断鼠标是否在滚动条区域移动 if (VScroll.Bounds.Contains(MousePos)) { ClearItemMouseOn(); ClearSubItemMouseOn(); if (VScroll.SliderBounds.Contains(MousePos)) { VScroll.IsMouseOnSlider = true; } else { VScroll.IsMouseOnSlider = false; } if (VScroll.UpBounds.Contains(MousePos)) { VScroll.IsMouseOnUp = true; } else { VScroll.IsMouseOnUp = false; } if (VScroll.DownBounds.Contains(MousePos)) { VScroll.IsMouseOnDown = true; } else { VScroll.IsMouseOnDown = false; } return; } else { VScroll.ClearAllMouseOn(); } } MousePos.Y += VScroll.Value; //如果不在滚动条范围类 那么根据滚动条当前值计算虚拟的一个坐标 for (int i = 0, Len = items.Count; i < Len; i++) { //然后判断鼠标是否移动到某一列表项或者子项 if (items[i].Bounds.Contains(MousePos)) { if (items[i].IsOpen) { //如果展开 判断鼠标是否在某一子项上面 for (int j = 0, lenSubItem = items[i].SubItems.Count; j < lenSubItem; j++) { if (items[i].SubItems[j].Bounds.Contains(MousePos)) { if (MouseOnSongItem != null) { //如果当前鼠标下子项不为空 if (items[i].SubItems[j].HeadRect.Contains(MousePos)) { //判断鼠标是否在头像内 if (!OnMouseEnterHeaded) { //如果没有触发进入事件 那么触发用户绑定的事件 OnMouseEnterHead(new ChatListEventArgs(this.MouseOnSongItem, this.selectSubItem)); OnMouseEnterHeaded = true; } } else { if (OnMouseEnterHeaded) { //如果已经执行过进入事件 那触发用户绑定的离开事件 OnMouseLeaveHead(new ChatListEventArgs(this.MouseOnSongItem, this.selectSubItem)); OnMouseEnterHeaded = false; } } } if (items[i].SubItems[j].Equals(MouseOnSongItem)) { return; } ClearSubItemMouseOn(); ClearItemMouseOn(); MouseOnSongItem = items[i].SubItems[j]; this.Invalidate(new Rectangle( MouseOnSongItem.Bounds.X, MouseOnSongItem.Bounds.Y - VScroll.Value, MouseOnSongItem.Bounds.Width, MouseOnSongItem.Bounds.Height)); //this.Invalidate(); return; } } ClearSubItemMouseOn(); //循环做完没发现子项 那么判断是否在列表上面 if (new Rectangle(0, items[i].Bounds.Top - VScroll.Value, this.Width, 20).Contains(e.Location)) { if (items[i].Equals(MouseOnList)) { return; } ClearItemMouseOn(); MouseOnList = items[i]; this.Invalidate(new Rectangle( MouseOnList.Bounds.X, MouseOnList.Bounds.Y - VScroll.Value, MouseOnList.Bounds.Width, MouseOnList.Bounds.Height)); //this.Invalidate(); return; } } else { //如果列表项没有展开 重绘列表项 if (items[i].Equals(MouseOnList)) { return; } ClearItemMouseOn(); ClearSubItemMouseOn(); MouseOnList = items[i]; this.Invalidate(new Rectangle( MouseOnList.Bounds.X, MouseOnList.Bounds.Y - VScroll.Value, MouseOnList.Bounds.Width, MouseOnList.Bounds.Height)); //this.Invalidate(); return; } } }//若循环结束 既不在列表上也不再子项上 清空上面的颜色 ClearItemMouseOn(); ClearSubItemMouseOn(); base.OnMouseMove(e); }
/// <summary> /// 判断子项是否在集合内 /// </summary> /// <param name="subItem">要判断的子项</param> /// <returns>是否在集合内</returns> public bool Contains(SongItem subItem) { return(this.IndexOf(subItem) != -1); }
/// <summary> /// 获取索引位置 /// </summary> /// <param name="subItem">要获取索引的子项</param> /// <returns>索引</returns> public int IndexOf(SongItem subItem) { return(Array.IndexOf <SongItem>(m_arrSubItems, subItem)); }
public ChatListEventArgs(SongItem mouseonsubitem, SongItem selectsubitem) { this.mouseOnSubItem = mouseonsubitem; this.selectSubItem = selectsubitem; }