2014-04-21 14 views
0

我要创建使用.NET GUI应用程序,我需要实现此类定制项目滚动列表。所有项目应进行分组,以3个不同的组,包括图像,文本和喜爱的明星按钮,如下所示:什么是建立在C#.NET自定义项目滚动列表视图的最佳方式?

mockup

我也想实现使用搜索框过滤,但一旦我将能够创建这样的列表与可定制的项目,然后我希望它会容易得多。

我尝试使用.NET列表视图,但我希望每个单元格看起来像1单元格 - 与图像,文本,图像之间的任何边界。

我会非常感激这个方式有什么想法!

+1

这看起来像一个想法任务WPF。如果您需要在WinForms中执行此操作,将会变得更加棘手。 –

+0

WinForms的任何想法?你建议WPF使用哪个组件? –

+0

我不知道任何事先建立在WinForms或WPF中的东西都可以做到你想要的东西。你一定要做一些定制的工作。在WPF中,这将是一个其中包含其他元素的stackPanel。 –

回答

1

最好的办法是为WPF ListViewListBox控件制作控件模板。

例如,ListBox.ItemTemplate允许自定义项目的外观。

如果你想使用第三方组件,Better ListView允许这种使用所有者绘制(需要子类BetterListView):

enter image description here

下面是该控件的安装代码:

this.customListView = new CustomListView 
         { 
          Dock = DockStyle.Fill, 
          Parent = this 
         }; 

this.customListView.BeginUpdate(); 

for (int i = 0; i < 6; i++) 
{ 
    var item = new BetterListViewItem 
       { 
        Image = imageGraph, 
        Text = String.Format("Item no. {0}", i) 
       }; 

    this.customListView.Items.Add(item); 
} 

var group1 = new BetterListViewGroup("First group"); 
var group2 = new BetterListViewGroup("Second group"); 
var group3 = new BetterListViewGroup("Third group"); 

this.customListView.Groups.AddRange(new[] { group1, group2, group3 }); 

this.customListView.Items[0].Group = group1; 
this.customListView.Items[1].Group = group1; 

this.customListView.Items[2].Group = group2; 
this.customListView.Items[3].Group = group2; 
this.customListView.Items[4].Group = group2; 

this.customListView.Items[5].Group = group3; 

this.customListView.AutoSizeItemsInDetailsView = true; 
this.customListView.GroupHeaderBehavior = BetterListViewGroupHeaderBehavior.None; 
this.customListView.ShowGroups = true; 

this.customListView.LayoutItemsCurrent.ElementOuterPadding = new Size(0, 8); 

this.customListView.EndUpdate(); 

CustomListView类(实现与明星图标自定义绘制和交互):

using BetterListView; 

internal sealed class CustomListView : BetterListView 
{ 
    private const int IndexUndefined = -1; 

    private Image imageStarNormal; 
    private Image imageStarHighlight; 

    private int lastStarIndex = IndexUndefined; 
    private int currentStarIndex = IndexUndefined; 

    public CustomListView() 
    { 
     this.imageStarNormal = Image.FromFile("icon-star-normal.png"); 
     this.imageStarHighlight = Image.FromFile("icon-star-highlight.png"); 
    } 

    protected override void OnMouseMove(MouseEventArgs e) 
    { 
     base.OnMouseMove(e); 

     var item = HitTest(e.Location).ItemDisplay; 

     if (item == null) 
     { 
      return; 
     } 

     var bounds = GetItemBounds(item); 

     if (bounds == null) 
     { 
      return; 
     } 

     Rectangle boundsStar = GetStarBounds(bounds); 

     UpdateStarIndex(boundsStar.Contains(e.Location) 
      ? item.Index 
      : IndexUndefined); 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     base.OnMouseLeave(e); 
     UpdateStarIndex(IndexUndefined); 
    } 

    protected override void OnDrawGroup(BetterListViewDrawGroupEventArgs eventArgs) 
    { 
     eventArgs.DrawSeparator = false; 

     base.OnDrawGroup(eventArgs); 
    } 

    protected override void OnDrawItem(BetterListViewDrawItemEventArgs eventArgs) 
    { 
     base.OnDrawItem(eventArgs); 

     Graphics g = eventArgs.Graphics; 
     BetterListViewItemBounds bounds = eventArgs.ItemBounds; 

     int imageWidth = this.imageStarNormal.Width; 
     int imageHeight = this.imageStarNormal.Height; 

     g.DrawImage(
      (this.currentStarIndex == eventArgs.Item.Index) ? this.imageStarHighlight : this.imageStarNormal, 
      GetStarBounds(bounds), 
      0, 0, imageWidth, imageHeight, 
      GraphicsUnit.Pixel); 

     Rectangle boundsSelection = bounds.BoundsSelection; 

     g.DrawRectangle(
      Pens.Gray, 
      new Rectangle(boundsSelection.Left, boundsSelection.Top, boundsSelection.Width - 1, boundsSelection.Height - 1)); 
    } 

    private void UpdateStarIndex(int starIndex) 
    { 
     if (starIndex == this.lastStarIndex) 
     { 
      return; 
     } 

     bool isUpdated = false; 

     if (this.lastStarIndex != IndexUndefined) 
     { 
      Items[this.lastStarIndex].Invalidate(); 

      isUpdated = true; 
     } 

     if (starIndex != IndexUndefined) 
     { 
      Items[starIndex].Invalidate(); 

      isUpdated = true; 
     } 

     this.lastStarIndex = this.currentStarIndex; 
     this.currentStarIndex = starIndex; 

     if (isUpdated) 
     { 
      RedrawItems(); 
     } 
    } 

    private Rectangle GetStarBounds(BetterListViewItemBounds bounds) 
    { 
     Rectangle rectInner = bounds.BoundsInner; 

     int widthImage = this.imageStarNormal.Width; 
     int heightImage = this.imageStarNormal.Height; 

     return (new Rectangle(
      rectInner.Width - widthImage, 
      rectInner.Top + ((rectInner.Height - heightImage) >> 1), 
      widthImage, 
      heightImage)); 
    } 
} 
相关问题