1 
  
     2 
  
     3 
  
     4 
  
     5 
  
     6 using System;
  
     7 using System.Collections;
  
     8 
  
     9 namespace System.Windows
  
    10 {
  
    11     public class ListViewItemEventArgs
  
    12     {
  
    13         public ListViewItemEventArgs(ListView* view_, ListViewItem* item_) : view(view_), item(item_), location(), control(false), errorId(0)
  
    14         {
  
    15         }
  
    16         public ListView* view;
  
    17         public ListViewItem* item;
  
    18         public Point location;
  
    19         public bool control;
  
    20         public int errorId;
  
    21     }
  
    22 
  
    23     public class ListViewColumnEventArgs
  
    24     {
  
    25         public ListViewColumnEventArgs(ListView* view_, ListViewColumn* column_) : view(view_), column(column_)
  
    26         {
  
    27         }
  
    28         public ListView* view;
  
    29         public ListViewColumn* column;
  
    30     }
  
    31 
  
    32     public class delegate void ListViewItemEventHandler(ListViewItemEventArgs& args);
  
    33     public class delegate void ListViewColumnEventHandler(ListViewColumnEventArgs& args);
  
    34 
  
    35     public Color DefaultListViewBackgroundColor()
  
    36     {
  
    37         return Color.White();
  
    38     }
  
    39 
  
    40     public string DefaultListViewFontFamilyName()
  
    41     {
  
    42         return "Segoe UI";
  
    43     }
  
    44 
  
    45     public float DefaultListViewFontSize()
  
    46     {
  
    47         return 9.000000f;
  
    48     }
  
    49 
  
    50     public Color DefaultListViewColumnTextColor()
  
    51     {
  
    52         return Color(76u, 96u, 122u);
  
    53     }
  
    54 
  
    55     public Color DefaultListViewItemTextColor()
  
    56     {
  
    57         return Color.Black();
  
    58     }
  
    59 
  
    60     public Color DefaultListViewDisabledItemTextColor()
  
    61     {
  
    62         return Color(201u, 201u, 201u);
  
    63     }
  
    64 
  
    65     public Color DefaultListViewColumnDividerColor()
  
    66     {
  
    67         return Color(229u, 229u, 229u);
  
    68     }
  
    69 
  
    70     public Color DefaultListViewItemSelectedColor()
  
    71     {
  
    72         return Color(204u, 232u, 255u);
  
    73     }
  
    74 
  
    75     public Padding DefaultListViewColumnHeaderPadding()
  
    76     {
  
    77         return Padding(4, 0, 4, 4);
  
    78     }
  
    79 
  
    80     public Padding DefaultListViewItemPadding()
  
    81     {
  
    82         return Padding(4, 0, 4, 0);
  
    83     }
  
    84 
  
    85     public Padding DefaultListViewItemColumnPadding()
  
    86     {
  
    87         return Padding(4, 0, 4, 0);
  
    88     }
  
    89 
  
    90     public Padding DefaultListViewColumnDividerPadding()
  
    91     {
  
    92         return Padding(1, 0, 1, 0);
  
    93     }
  
    94 
  
    95     public Padding DefaultListViewImagePadding()
  
    96     {
  
    97         return Padding(2, 2, 2, 2);
  
    98     }
  
    99 
  
   100     public ControlCreateParams& ListViewControlCreateParams(ControlCreateParams& controlCreateParams)
  
   101     {
  
   102         return controlCreateParams.SetWindowClassName("System.Windows.ListView").SetWindowClassStyle(DoubleClickWindowClassStyle()).
  
   103             SetWindowClassBackgroundColor(SystemColor.COLOR_WINDOW).SetBackgroundColor(DefaultListViewBackgroundColor());
  
   104     }
  
   105 
  
   106     public class ListViewCreateParams
  
   107     {
  
   108         public ListViewCreateParams(ControlCreateParams& controlCreateParams_) : 
  
   109             controlCreateParams(controlCreateParams_), 
  
   110             allowMultiselect(false), 
  
   111             fontFamilyName(DefaultListViewFontFamilyName()), 
  
   112             fontSize(DefaultListViewFontSize()), 
  
   113             columnTextColor(DefaultListViewColumnTextColor()), 
  
   114             itemTextColor(DefaultListViewItemTextColor()), 
  
   115             disabledItemTextColor(DefaultListViewDisabledItemTextColor()), 
  
   116             columnDividerColor(DefaultListViewColumnDividerColor()), 
  
   117             itemSelectedColor(DefaultListViewItemSelectedColor()), 
  
   118             columnHeaderPadding(DefaultListViewColumnHeaderPadding()), 
  
   119             itemPadding(DefaultListViewItemPadding()), 
  
   120             itemColumnPadding(DefaultListViewItemColumnPadding()), 
  
   121             columnDividerPadding(DefaultListViewColumnDividerPadding()), 
  
   122             imagePadding(DefaultListViewImagePadding())
  
   123         {
  
   124         }
  
   125         public ListViewCreateParams& Defaults()
  
   126         {
  
   127             return *this;
  
   128         }
  
   129         public ListViewCreateParams& SetAllowMultiselect(bool allowMultiselect_)
  
   130         {
  
   131             allowMultiselect = allowMultiselect_;
  
   132             return *this;
  
   133         }
  
   134         public ListViewCreateParams& SetFontFamilyName(const string& fontFamilyName_)
  
   135         {
  
   136             fontFamilyName = fontFamilyName_;
  
   137             return *this;
  
   138         }
  
   139         public ListViewCreateParams& SetFontSize(float fontSize_)
  
   140         {
  
   141             fontSize = fontSize_;
  
   142             return *this;
  
   143         }
  
   144         public ListViewCreateParams& SetColumnTextColor(const Color& columnTextColor_)
  
   145         {
  
   146             columnTextColor = columnTextColor_;
  
   147             return *this;
  
   148         }
  
   149         public ListViewCreateParams& SetItemTextColor(const Color& itemTextColor_)
  
   150         {
  
   151             itemTextColor = itemTextColor_;
  
   152             return *this;
  
   153         }
  
   154         public ListViewCreateParams& SetDisabledItemTextColor(const Color& disabledItemTextColor_)
  
   155         {
  
   156             disabledItemTextColor = disabledItemTextColor_;
  
   157             return *this;
  
   158         }
  
   159         public ListViewCreateParams& SetColumnDividerColor(const Color& columnDividerColor_)
  
   160         {
  
   161             columnDividerColor = columnDividerColor_;
  
   162             return *this;
  
   163         }
  
   164         public ListViewCreateParams& SetItemSelectedColor(const Color& itemSelectedColor_)
  
   165         {
  
   166             itemSelectedColor = itemSelectedColor_;
  
   167             return *this;
  
   168         }
  
   169         public ListViewCreateParams& SetColumnHeaderPadding(const Padding& columnHeaderPadding_)
  
   170         {
  
   171             columnHeaderPadding = columnHeaderPadding_;
  
   172             return *this;
  
   173         }
  
   174         public ListViewCreateParams& SetItemPadding(const Padding& itemPadding_)
  
   175         {
  
   176             itemPadding = itemPadding_;
  
   177             return *this;
  
   178         }
  
   179         public ListViewCreateParams& SetItemColumnPadding(const Padding& itemColumnPadding_)
  
   180         {
  
   181             itemColumnPadding = itemColumnPadding_;
  
   182             return *this;
  
   183         }
  
   184         public ListViewCreateParams& SetColumnDividerPadding(const Padding& columnDividerPadding_)
  
   185         {
  
   186             columnDividerPadding = columnDividerPadding_;
  
   187             return *this;
  
   188         }
  
   189         public ListViewCreateParams& SetImagePadding(const Padding& imagePadding_)
  
   190         {
  
   191             imagePadding = imagePadding_;
  
   192             return *this;
  
   193         }
  
   194         public ControlCreateParams& controlCreateParams;
  
   195         public bool allowMultiselect;
  
   196         public string fontFamilyName;
  
   197         public float fontSize;
  
   198         public Color columnTextColor;
  
   199         public Color itemTextColor;
  
   200         public Color disabledItemTextColor;
  
   201         public Color columnDividerColor;
  
   202         public Color itemSelectedColor;
  
   203         public Padding columnHeaderPadding;
  
   204         public Padding itemPadding;
  
   205         public Padding itemColumnPadding;
  
   206         public Padding columnDividerPadding;
  
   207         public Padding imagePadding;
  
   208     }
  
   209 
  
   210     public class ListView : Control
  
   211     {
  
   212         public enum Flags : int
  
   213         {
  
   214             none = 0, measured = 1 << 0, allowMultiselect = 1 << 1
  
   215         }
  
   216         public ListView(ListViewCreateParams& createParams) : 
  
   217             base(createParams.controlCreateParams), 
  
   218             flags(Flags.none), imageList(null), 
  
   219             columnHeaderTextBrush(createParams.columnTextColor), 
  
   220             itemTextBrush(createParams.itemTextColor), 
  
   221             disabledItemTextBrush(createParams.disabledItemTextColor), 
  
   222             itemSelectedBrush(createParams.itemSelectedColor), 
  
   223             columnDividerPen(createParams.columnDividerColor), 
  
   224             stringFormat(), 
  
   225             columnHeaderPadding(createParams.columnHeaderPadding), 
  
   226             itemPadding(createParams.itemPadding), 
  
   227             itemColumnPadding(createParams.itemColumnPadding), 
  
   228             columnDividerPadding(createParams.columnDividerPadding), 
  
   229             imagePadding(createParams.imagePadding), 
  
   230             charWidth(0), 
  
   231             charHeight(0), 
  
   232             columnDividerWidth(1), 
  
   233             ellipsisWidth(0), 
  
   234             mouseDownItem(null), 
  
   235             mouseEnterItem(null), 
  
   236             selectedItem(null), 
  
   237             mouseDownColumnDivider(null), 
  
   238             data(null), 
  
   239             arrowCursor(), 
  
   240             columnSizeCursor(null)
  
   241         {
  
   242             auto cursorResult = LoadStandardCursor(StandardCursorId.IDC_ARROW);
  
   243             if (cursorResult.Error())
  
   244             {
  
   245                 SetErrorId(cursorResult.GetErrorId());
  
   246                 return;
  
   247             }
  
   248             arrowCursor = Rvalue(cursorResult.Value());
  
   249             auto columnSizeCursorResult = Application.GetResourceManager().GetCursor("column.size.system.windows.cursor");
  
   250             if (columnSizeCursorResult.Error())
  
   251             {
  
   252                 SetErrorId(columnSizeCursorResult.GetErrorId());
  
   253                 return;
  
   254             }
  
   255             columnSizeCursor = Rvalue(columnSizeCursorResult.Value());
  
   256             if (createParams.allowMultiselect)
  
   257             {
  
   258                 SetFlag(Flags.allowMultiselect);
  
   259             }
  
   260             SetFont(Font(FontFamily(createParams.fontFamilyName), createParams.fontSize));
  
   261         }
  
   262         public inline ImageList* GetImageList() const
  
   263         {
  
   264             return imageList;
  
   265         }
  
   266         public void SetImageList(ImageList* imageList_)
  
   267         {
  
   268             imageList = imageList_;
  
   269         }
  
   270         public const StringFormat& GetStringFormat() const
  
   271         {
  
   272             return stringFormat;
  
   273         }
  
   274         public const Brush& ColumnHeaderTextBrush() const
  
   275         {
  
   276             return columnHeaderTextBrush;
  
   277         }
  
   278         public const Brush* ItemTextBrush() const
  
   279         {
  
   280             return &itemTextBrush;
  
   281         }
  
   282         public const Brush* DisabledItemTextBrush() const
  
   283         {
  
   284             return &disabledItemTextBrush;
  
   285         }
  
   286         public const Brush& ItemSelectedBrush() const
  
   287         {
  
   288             return itemSelectedBrush;
  
   289         }
  
   290         public const Pen& ColumnDividerPen() const
  
   291         {
  
   292             return columnDividerPen;
  
   293         }
  
   294         public const Padding& ColumnHeaderPadding() const
  
   295         {
  
   296             return columnHeaderPadding;
  
   297         }
  
   298         public const Padding& ItemPadding() const
  
   299         {
  
   300             return itemPadding;
  
   301         }
  
   302         public const Padding& ItemColumnPadding() const
  
   303         {
  
   304             return itemColumnPadding;
  
   305         }
  
   306         public const Padding& ColumnDividerPadding() const
  
   307         {
  
   308             return columnDividerPadding;
  
   309         }
  
   310         public const Padding& ImagePadding() const
  
   311         {
  
   312             return imagePadding;
  
   313         }
  
   314         public inline bool GetFlag(Flags flag) const
  
   315         {
  
   316             return (flags & flag) != Flags.none;
  
   317         }
  
   318         public void SetFlag(Flags flag)
  
   319         {
  
   320             flags = cast<Flags>(flags | flag);
  
   321         }
  
   322         public void ResetFlag(Flags flag)
  
   323         {
  
   324             flags = cast<Flags>(flags & ~flag);
  
   325         }
  
   326         public int ColumnCount() const
  
   327         {
  
   328             return cast<int>(columns.Count());
  
   329         }
  
   330         public void AddColumn(const string& name, int width)
  
   331         {
  
   332             ListViewColumn* column = new ListViewColumn(this, name, width);
  
   333             columns.Add(UniquePtr<ListViewColumn>(column));
  
   334             columnDividers.Add(UniquePtr<ListViewColumnDivider>(new ListViewColumnDivider(this, column)));
  
   335         }
  
   336         [nodiscard]
  
   337         public Result<ListViewColumn*> GetColumn(int columnIndex) const
  
   338         {
  
   339             if (columnIndex < 0 || columnIndex >= ColumnCount())
  
   340             {
  
   341                 int errorId = AllocateError("invalid column index");
  
   342                 return Result<ListViewColumn*>(ErrorId(errorId));
  
   343             }
  
   344             return Result<ListViewColumn*>(columns[columnIndex].Get());
  
   345         }
  
   346         public int ItemCount() const
  
   347         {
  
   348             return cast<int>(items.Count());
  
   349         }
  
   350         public ListViewItem* AddItem()
  
   351         {
  
   352             ListViewItem* item = new ListViewItem(this);
  
   353             items.Add(UniquePtr<ListViewItem>(item));
  
   354             return item;
  
   355         }
  
   356         [nodiscard]
  
   357         public Result<ListViewItem*> GetItem(int itemIndex) const
  
   358         {
  
   359             if (itemIndex < 0 || itemIndex >= ItemCount())
  
   360             {
  
   361                 int errorId = AllocateError("invalid item index");
  
   362                 return Result<ListViewItem*>(ErrorId(errorId));
  
   363             }
  
   364             return Result<ListViewItem*>(items[itemIndex].Get());
  
   365         }
  
   366         public inline ListViewItem* SelectedItem() const
  
   367         {
  
   368             return selectedItem;
  
   369         }
  
   370         [nodiscard]
  
   371         public Result<bool> SetSelectedItem(ListViewItem* selectedItem_)
  
   372         {
  
   373             if (GetFlag(Flags.allowMultiselect))
  
   374             {
  
   375                 auto result = ResetSelectedItems();
  
   376                 if (result.Error()) return result;
  
   377             }
  
   378             if (selectedItem != selectedItem_)
  
   379             {
  
   380                 if (selectedItem != null)
  
   381                 {
  
   382                     auto result = selectedItem->ResetSelected();
  
   383                     if (result.Error()) return result;
  
   384                 }
  
   385                 selectedItem = selectedItem_;
  
   386                 if (selectedItem != null)
  
   387                 {
  
   388                     auto result = selectedItem->SetSelected();
  
   389                     if (result.Error()) return result;
  
   390                 }
  
   391             }
  
   392             return Result<bool>(true);
  
   393         }
  
   394         public List<ListViewItem*> GetSelectedItems() const
  
   395         {
  
   396             List<ListViewItem*> result;
  
   397             for (const UniquePtr<ListViewItem>& item : items)
  
   398             {
  
   399                 if (item->IsSelected())
  
   400                 {
  
   401                     result.Add(item.Get());
  
   402                 }
  
   403             }
  
   404             return result;
  
   405         }
  
   406         [nodiscard]
  
   407         public Result<bool> ResetSelectedItems()
  
   408         {
  
   409             for (const UniquePtr<ListViewItem>& item : items)
  
   410             {
  
   411                 if (item.Get() != SelectedItem())
  
   412                 {
  
   413                     if (item->IsSelected())
  
   414                     {
  
   415                         auto result = item->ResetSelected();
  
   416                         if (result.Error()) return result;
  
   417                     }
  
   418                 }
  
   419             }
  
   420             return Result<bool>(true);
  
   421         }
  
   422         public ListViewItem* ItemAt(const Point& location) const
  
   423         {
  
   424             for (const UniquePtr<ListViewItem>& item : items)
  
   425             {
  
   426                 Rect rect(item->Location(), item->GetSize());
  
   427                 if (rect.Contains(location))
  
   428                 {
  
   429                     return item.Get();
  
   430                 }
  
   431             }
  
   432             return null;
  
   433         }
  
   434         public ListViewColumnDivider* ColumnDividerAt(const Point& location) const
  
   435         {
  
   436             for (const UniquePtr<ListViewColumnDivider>& columnDivider : columnDividers)
  
   437             {
  
   438                 Rect rect(columnDivider->Location(), columnDivider->GetSize());
  
   439                 if (rect.Contains(location))
  
   440                 {
  
   441                     return columnDivider.Get();
  
   442                 }
  
   443             }
  
   444             return null;
  
   445         }
  
   446         public inline float TextHeight() const
  
   447         {
  
   448             return charHeight;
  
   449         }
  
   450         public inline float ColumnDividerWidth() const
  
   451         {
  
   452             return columnDividerWidth;
  
   453         }
  
   454         public float EllipsisWidth() const
  
   455         {
  
   456             return ellipsisWidth;
  
   457         }
  
   458         public void FireColumnWidthChanged(ListViewColumn* column)
  
   459         {
  
   460             ListViewColumnEventArgs args(this, column);
  
   461             OnColumnWidthChanged(args);
  
   462         }
  
   463         public void SetData(void* data_)
  
   464         {
  
   465             data = data_;
  
   466         }
  
   467         public inline void* Data() const
  
   468         {
  
   469             return data;
  
   470         }
  
   471         public Event<ListViewItemEventHandler, ListViewItemEventArgs>& ItemClickEvent()
  
   472         {
  
   473             return itemClickEvent;
  
   474         }
  
   475         public Event<ListViewItemEventHandler, ListViewItemEventArgs>& ItemRightClickEvent()
  
   476         {
  
   477             return itemRightClickEvent;
  
   478         }
  
   479         public Event<ListViewItemEventHandler, ListViewItemEventArgs>& ItemDoubleClickEvent()
  
   480         {
  
   481             return itemDoubleClickEvent;
  
   482         }
  
   483         public Event<ListViewItemEventHandler, ListViewItemEventArgs>& ItemEnterEvent()
  
   484         {
  
   485             return itemEnterEvent;
  
   486         }
  
   487         public Event<ListViewItemEventHandler, ListViewItemEventArgs>& ItemLeaveEvent()
  
   488         {
  
   489             return itemLeaveEvent;
  
   490         }
  
   491         public Event<ListViewColumnEventHandler, ListViewColumnEventArgs>& ColumnWidthChangedEvent()
  
   492         {
  
   493             return columnWidthChangedEvent;
  
   494         }
  
   495         [nodiscard]
  
   496         protected override Result<bool> OnSizeChanged(SizeChangedEventArgs& args)
  
   497         {
  
   498             auto result = base->OnSizeChanged(args);
  
   499             if (result.Error()) return result;
  
   500             SetContentLocation(Point(0, 0));
  
   501             return Result<bool>(true);
  
   502         }
  
   503         [nodiscard]
  
   504         protected override Result<bool> OnPaint(PaintEventArgs& args)
  
   505         {
  
   506             if (!GetFlag(Flags.measured))
  
   507             {
  
   508                 SetFlag(Flags.measured);
  
   509                 auto result = Measure(args.graphics);
  
   510                 if (result.Error())
  
   511                 {
  
   512                     return Result<bool>(ErrorId(result.GetErrorId()));
  
   513                 }
  
   514             }
  
   515             Size contentSize(0, 0);
  
   516             auto result = args.graphics.Clear(BackgroundColor());
  
   517             if (result.Error()) return result;
  
   518             PointF origin;
  
   519             auto measureResult = MeasureItems(args.graphics, contentSize);
  
   520             if (measureResult.Error())
  
   521             {
  
   522                 return Result<bool>(ErrorId(measureResult.GetErrorId()));
  
   523             }
  
   524             result = DrawColumnHeader(args.graphics, origin);
  
   525             if (result.Error()) return result;
  
   526             result = DrawItems(args.graphics, origin);
  
   527             if (result.Error()) return result;
  
   528             result = SetContentSize(contentSize);
  
   529             if (result.Error()) return result;
  
   530             return base->OnPaint(args);
  
   531         }
  
   532         [nodiscard]
  
   533         protected override Result<bool> OnMouseDown(MouseEventArgs& args)
  
   534         {
  
   535             mouseDownItem = null;
  
   536             ListViewItem* item = ItemAt(args.location);
  
   537             if (item != null)
  
   538             {
  
   539                 mouseDownItem = item;
  
   540             }
  
   541             else
  
   542             {
  
   543                 auto result = SetSelectedItem(null);
  
   544                 if (result.Error()) return result;
  
   545             }
  
   546             if (args.buttons == MouseButtons.lbutton)
  
   547             {
  
   548                 ListViewColumnDivider* columnDivider = ColumnDividerAt(args.location);
  
   549                 if (columnDivider != null)
  
   550                 {
  
   551                     columnDivider->OnLButtonDown(args.location);
  
   552                     mouseDownColumnDivider = columnDivider;
  
   553                 }
  
   554             }
  
   555             return Result<bool>(true);
  
   556         }
  
   557         [nodiscard]
  
   558         protected override Result<bool> OnMouseUp(MouseEventArgs& args)
  
   559         {
  
   560             ListViewItem* item = ItemAt(args.location);
  
   561             if (item == mouseDownItem)
  
   562             {
  
   563                 ListViewItemEventArgs itemArgs(this, item);
  
   564                 if ((args.buttons & MouseButtons.lbutton) != MouseButtons.none)
  
   565                 {
  
   566                     if (GetFlag(Flags.allowMultiselect))
  
   567                     {
  
   568                         if ((args.buttons & MouseButtons.control) != MouseButtons.none)
  
   569                         {
  
   570                             itemArgs.control = true;
  
   571                         }
  
   572                     }
  
   573                     itemClickEvent.Fire(itemArgs);
  
   574                 }
  
   575                 else if (args.buttons == MouseButtons.rbutton)
  
   576                 {
  
   577                     itemArgs.location = args.location;
  
   578                     itemRightClickEvent.Fire(itemArgs);
  
   579                 }
  
   580                 if (itemArgs.errorId != 0)
  
   581                 {
  
   582                     return Result<bool>(ErrorId(itemArgs.errorId));
  
   583                 }
  
   584             }
  
   585             mouseDownItem = null;
  
   586             if (args.buttons == MouseButtons.lbutton)
  
   587             {
  
   588                 if (mouseDownColumnDivider != null)
  
   589                 {
  
   590                     mouseDownColumnDivider->OnLButtonUp();
  
   591                     mouseDownColumnDivider = null;
  
   592                 }
  
   593             }
  
   594             return Result<bool>(true);
  
   595         }
  
   596         [nodiscard]
  
   597         protected override Result<bool> OnMouseDoubleClick(MouseEventArgs& args)
  
   598         {
  
   599             ListViewItem* item = ItemAt(args.location);
  
   600             if (item != null)
  
   601             {
  
   602                 ListViewItemEventArgs args(this, item);
  
   603                 itemDoubleClickEvent.Fire(args);
  
   604             }
  
   605             mouseDownItem = null;
  
   606             return Result<bool>(true);
  
   607         }
  
   608         [nodiscard]
  
   609         protected override Result<bool> OnMouseEnter(EnterLeaveEventArgs& args)
  
   610         {
  
   611             mouseEnterItem = null;
  
   612             return Result<bool>(true);
  
   613         }
  
   614         protected override Result<bool> OnMouseLeave(EnterLeaveEventArgs& args)
  
   615         {
  
   616             if (mouseEnterItem != null)
  
   617             {
  
   618                 ListViewItemEventArgs leaveItemArgs(this, mouseEnterItem);
  
   619                 itemLeaveEvent.Fire(leaveItemArgs);
  
   620                 mouseEnterItem = null;
  
   621             }
  
   622             return Result<bool>(true);
  
   623         }
  
   624         [nodiscard]
  
   625         protected override Result<bool> OnMouseMove(MouseEventArgs& args)
  
   626         {
  
   627             if (mouseEnterItem == null)
  
   628             {
  
   629                 mouseEnterItem = ItemAt(args.location);
  
   630                 if (mouseEnterItem != null)
  
   631                 {
  
   632                     ListViewItemEventArgs itemArgs(this, mouseEnterItem);
  
   633                     itemEnterEvent.Fire(itemArgs);
  
   634                 }
  
   635             }
  
   636             else
  
   637             {
  
   638                 ListViewItem* item = ItemAt(args.location);
  
   639                 if (item != mouseEnterItem)
  
   640                 {
  
   641                     ListViewItemEventArgs leaveItemArgs(this, mouseEnterItem);
  
   642                     itemLeaveEvent.Fire(leaveItemArgs);
  
   643                     mouseEnterItem = item;
  
   644                     if (mouseEnterItem != null)
  
   645                     {
  
   646                         ListViewItemEventArgs enterItemArgs(this, mouseEnterItem);
  
   647                         itemEnterEvent.Fire(enterItemArgs);
  
   648                     }
  
   649                 }
  
   650             }
  
   651             if (args.buttons == MouseButtons.lbutton)
  
   652             {
  
   653                 if (mouseDownColumnDivider != null)
  
   654                 {
  
   655                     if (mouseDownColumnDivider->HasMouseCapture())
  
   656                     {
  
   657                         auto result = mouseDownColumnDivider->OnMouseMove(args.location);
  
   658                         if (result.Error()) return result;
  
   659                     }
  
   660                 }
  
   661             }
  
   662             return Result<bool>(true);
  
   663         }
  
   664         protected virtual void OnColumnWidthChanged(ListViewColumnEventArgs& args)
  
   665         {
  
   666             columnWidthChangedEvent.Fire(args);
  
   667         }
  
   668         protected override Result<bool> SetCursor()
  
   669         {
  
   670             Point pt;
  
   671             auto cpResult = GetCursorPos(pt.x, pt.y);
  
   672             if (cpResult.Error()) return cpResult;
  
   673             auto result = ScreenToClient(pt);
  
   674             if (result.Error())
  
   675             {
  
   676                 return Result<bool>(ErrorId(result.GetErrorId()));
  
   677             }
  
   678             Point cursorPos = result.Value();
  
   679             bool cursorSet = false;
  
   680             for (const UniquePtr<ListViewColumnDivider>& columnDivider : columnDividers)
  
   681             {
  
   682                 Rect r(columnDivider->Location(), columnDivider->GetSize());
  
   683                 if (r.Contains(cursorPos))
  
   684                 {
  
   685                     System.Windows.SetCursor(columnSizeCursor);
  
   686                     cursorSet = true;
  
   687                     break;
  
   688                 }
  
   689             }
  
   690             if (!cursorSet)
  
   691             {
  
   692                 System.Windows.SetCursor(&arrowCursor);
  
   693             }
  
   694             return Result<bool>(true);
  
   695         }
  
   696         private Result<bool> Measure(Graphics& graphics)
  
   697         {
  
   698             auto measureResult = graphics.MeasureStringRectF("This is test string", GetFont(), PointF(0, 0), stringFormat);
  
   699             if (measureResult.Error())
  
   700             {
  
   701                 return Result<bool>(ErrorId(measureResult.GetErrorId()));
  
   702             }
  
   703             RectF charRect = measureResult.Value();
  
   704             charHeight = charRect.size.h;
  
   705             charWidth = charRect.size.w;
  
   706             SetScrollUnits(cast<int>(charHeight + 0.500000f), cast<int>(2 * (charWidth + 0.500000f)));
  
   707             measureResult = graphics.MeasureStringRectF("...", GetFont(), PointF(0, 0), stringFormat);
  
   708             if (measureResult.Error())
  
   709             {
  
   710                 return Result<bool>(ErrorId(measureResult.GetErrorId()));
  
   711             }
  
   712             RectF ellipsisRect = measureResult.Value();
  
   713             ellipsisWidth = ellipsisRect.size.w;
  
   714             return Result<bool>(true);
  
   715         }
  
   716         private Result<bool> MeasureItems(Graphics& graphics, Size& contentSize)
  
   717         {
  
   718             int maxWidth = 0;
  
   719             Point loc(itemPadding.left, cast<int>(charHeight + 0.500000f + columnHeaderPadding.Vertical()));
  
   720             for (const UniquePtr<ListViewItem>& item : items)
  
   721             {
  
   722                 item->SetLocation(loc);
  
   723                 auto measureResult = item->Measure(graphics);
  
   724                 if (measureResult.Error())
  
   725                 {
  
   726                     return Result<bool>(ErrorId(measureResult.GetErrorId()));
  
   727                 }
  
   728                 Size itemSize = item->GetSize();
  
   729                 loc.y = loc.y + itemSize.h;
  
   730                 maxWidth = Max(maxWidth, itemSize.w);
  
   731             }
  
   732             contentSize.w = Max(contentSize.w, maxWidth);
  
   733             contentSize.h = Max(contentSize.h, loc.y);
  
   734             return Result<bool>(true);
  
   735         }
  
   736         private Result<bool> DrawColumnHeader(Graphics& graphics, PointF& origin)
  
   737         {
  
   738             PointF headerOrigin = origin;
  
   739             headerOrigin.x = headerOrigin.x + columnHeaderPadding.left;
  
   740             headerOrigin.y = headerOrigin.y + columnHeaderPadding.top;
  
   741             long n = columns.Count();
  
   742             for (long i = 0; i < n; ++i;)
  
   743             {
  
   744                 ListViewColumn* column = columns[i].Get();
  
   745                 auto drawResult = column->Draw(graphics, headerOrigin);
  
   746                 if (drawResult.Error())
  
   747                 {
  
   748                     return Result<bool>(ErrorId(drawResult.GetErrorId()));
  
   749                 }
  
   750                 headerOrigin.x = headerOrigin.x + column->Width() + columnHeaderPadding.Horizontal();
  
   751                 ListViewColumnDivider* divider = columnDividers[i].Get();
  
   752                 headerOrigin.x = headerOrigin.x + columnDividerPadding.left;
  
   753                 drawResult = divider->Draw(graphics, headerOrigin);
  
   754                 if (drawResult.Error())
  
   755                 {
  
   756                     return Result<bool>(ErrorId(drawResult.GetErrorId()));
  
   757                 }
  
   758                 headerOrigin.x = headerOrigin.x + columnDividerWidth + columnDividerPadding.right;
  
   759             }
  
   760             origin.y = origin.y + charHeight + columnHeaderPadding.Vertical();
  
   761             return Result<bool>(true);
  
   762         }
  
   763         private Result<bool> DrawItems(Graphics& graphics, PointF& origin)
  
   764         {
  
   765             for (const UniquePtr<ListViewItem>& item : items)
  
   766             {
  
   767                 PointF itemOrigin = origin;
  
   768                 itemOrigin.y = itemOrigin.y + itemPadding.top;
  
   769                 itemOrigin.x = itemOrigin.x + itemPadding.left;
  
   770                 auto drawResult = item->Draw(graphics, itemOrigin);
  
   771                 if (drawResult.Error())
  
   772                 {
  
   773                     return Result<bool>(ErrorId(drawResult.GetErrorId()));
  
   774                 }
  
   775                 Size sz = item->GetSize();
  
   776                 origin.y = origin.y + sz.h;
  
   777             }
  
   778             return Result<bool>(true);
  
   779         }
  
   780         private Flags flags;
  
   781         private ImageList* imageList;
  
   782         private SolidBrush columnHeaderTextBrush;
  
   783         private SolidBrush itemTextBrush;
  
   784         private SolidBrush disabledItemTextBrush;
  
   785         private SolidBrush itemSelectedBrush;
  
   786         private Pen columnDividerPen;
  
   787         private StringFormat stringFormat;
  
   788         private Padding columnHeaderPadding;
  
   789         private Padding itemPadding;
  
   790         private Padding itemColumnPadding;
  
   791         private Padding columnDividerPadding;
  
   792         private Padding imagePadding;
  
   793         private float charWidth;
  
   794         private float charHeight;
  
   795         private float columnDividerWidth;
  
   796         private float ellipsisWidth;
  
   797         private ListViewItem* mouseDownItem;
  
   798         private ListViewItem* mouseEnterItem;
  
   799         private ListViewItem* selectedItem;
  
   800         private ListViewColumnDivider* mouseDownColumnDivider;
  
   801         private void* data;
  
   802         private Cursor arrowCursor;
  
   803         private Cursor* columnSizeCursor;
  
   804         private List<UniquePtr<ListViewColumn>> columns;
  
   805         private List<UniquePtr<ListViewColumnDivider>> columnDividers;
  
   806         private List<UniquePtr<ListViewItem>> items;
  
   807         private Event<ListViewItemEventHandler, ListViewItemEventArgs> itemClickEvent;
  
   808         private Event<ListViewItemEventHandler, ListViewItemEventArgs> itemRightClickEvent;
  
   809         private Event<ListViewItemEventHandler, ListViewItemEventArgs> itemDoubleClickEvent;
  
   810         private Event<ListViewItemEventHandler, ListViewItemEventArgs> itemEnterEvent;
  
   811         private Event<ListViewItemEventHandler, ListViewItemEventArgs> itemLeaveEvent;
  
   812         private Event<ListViewColumnEventHandler, ListViewColumnEventArgs> columnWidthChangedEvent;
  
   813     }
  
   814 
  
   815     public class ListViewColumn
  
   816     {
  
   817         public ListViewColumn(ListView* view_, const string& name_, int width_) : 
  
   818             view(view_), name(name_), width(width_), minWidth(0)
  
   819         {
  
   820         }
  
   821         public inline const string& Name() const
  
   822         {
  
   823             return name;
  
   824         }
  
   825         public inline int Width() const
  
   826         {
  
   827             return width;
  
   828         }
  
   829         [nodiscard]
  
   830         public Result<bool> SetWidth(int width_)
  
   831         {
  
   832             if (width != width_)
  
   833             {
  
   834                 width = width_;
  
   835                 view->FireColumnWidthChanged(this);
  
   836                 auto result = view->Invalidate();
  
   837                 if (result.Error()) return result;
  
   838             }
  
   839             return Result<bool>(true);
  
   840         }
  
   841         public inline int MinWidth() const
  
   842         {
  
   843             return minWidth;
  
   844         }
  
   845         public void SetMinWidth(int minWidth_)
  
   846         {
  
   847             minWidth = minWidth_;
  
   848         }
  
   849         [nodiscard]
  
   850         public Result<bool> Draw(Graphics& graphics, const PointF& origin)
  
   851         {
  
   852             auto drawResult = graphics.DrawString(name, view->GetFont(), origin, view->ColumnHeaderTextBrush());
  
   853             return drawResult;
  
   854         }
  
   855         private ListView* view;
  
   856         private string name;
  
   857         private int width;
  
   858         private int minWidth;
  
   859     }
  
   860 
  
   861     public class ListViewColumnDivider
  
   862     {
  
   863         public ListViewColumnDivider(ListView* view_, ListViewColumn* column_) : 
  
   864             view(view_), column(column_), location(), startCapturePos(), startColumnWidth(0), hasMouseCapture(false)
  
   865         {
  
   866         }
  
   867         public inline const Point& Location() const
  
   868         {
  
   869             return location;
  
   870         }
  
   871         public Size GetSize() const
  
   872         {
  
   873             return Size(cast<int>(view->ColumnDividerWidth() + 4 * view->ColumnDividerPadding().Horizontal() + 0.500000f), cast<int>(view->TextHeight() + 0.500000f));
  
   874         }
  
   875         public inline bool HasMouseCapture() const
  
   876         {
  
   877             return hasMouseCapture;
  
   878         }
  
   879         public void OnLButtonDown(const Point& pos)
  
   880         {
  
   881             WinSetCapture(view->Handle());
  
   882             startCapturePos = pos;
  
   883             startColumnWidth = column->Width();
  
   884             hasMouseCapture = true;
  
   885         }
  
   886         [nodiscard]
  
   887         public Result<bool> OnMouseMove(const Point& pos)
  
   888         {
  
   889             auto result = column->SetWidth(Max(column->MinWidth(), startColumnWidth + pos.x - startCapturePos.x));
  
   890             if (result.Error()) return result;
  
   891             return Result<bool>(true);
  
   892         }
  
   893         public void OnLButtonUp()
  
   894         {
  
   895             WinReleaseCapture();
  
   896             hasMouseCapture = false;
  
   897         }
  
   898         [nodiscard]
  
   899         public Result<bool> Draw(Graphics& graphics, const PointF& origin)
  
   900         {
  
   901             const Pen& pen = view->ColumnDividerPen();
  
   902             Size sz = GetSize();
  
   903             location = Point(cast<int>(origin.x - sz.w / 2), cast<int>(origin.y));
  
   904             PointF end = origin;
  
   905             end.y = end.y + view->TextHeight();
  
   906             auto drawResult = graphics.DrawLine(pen, origin, end);
  
   907             return drawResult;
  
   908         }
  
   909         private ListView* view;
  
   910         private ListViewColumn* column;
  
   911         private Point location;
  
   912         private Point startCapturePos;
  
   913         private int startColumnWidth;
  
   914         private bool hasMouseCapture;
  
   915     }
  
   916 
  
   917     public class ListViewItem
  
   918     {
  
   919         public enum Flags : int
  
   920         {
  
   921             none = 0, disabled = 1 << 0, selected = 1 << 1
  
   922         }
  
   923         public enum State : int
  
   924         {
  
   925             enabled, disabled
  
   926         }
  
   927         public explicit ListViewItem(ListView* view_) : view(view_), flags(Flags.none), imageIndex(-1), disabledImageIndex(-1), data(null)
  
   928         {
  
   929         }
  
   930         [nodiscard]
  
   931         public Result<bool> SetColumnValue(int columnIndex, const string& columnValue)
  
   932         {
  
   933             if (columnIndex < 0)
  
   934             {
  
   935                 int errorId = AllocateError("invalid column index");
  
   936                 return Result<bool>(ErrorId(errorId));
  
   937             }
  
   938             while (columnIndex >= columnValues.Count())
  
   939             {
  
   940                 columnValues.Add(string());
  
   941             }
  
   942             columnValues[columnIndex] = columnValue;
  
   943             return Result<bool>(true);
  
   944         }
  
   945         [nodiscard]
  
   946         public Result<string> GetColumnValue(int columnIndex) const
  
   947         {
  
   948             if (columnIndex < 0)
  
   949             {
  
   950                 int errorId = AllocateError("invalid column index");
  
   951                 return Result<string>(ErrorId(errorId));
  
   952             }
  
   953             if (columnIndex >= columnValues.Count())
  
   954             {
  
   955                 return string();
  
   956             }
  
   957             return Result<string>(columnValues[columnIndex]);
  
   958         }
  
   959         [nodiscard]
  
   960         public Result<bool> Draw(Graphics& graphics, PointF& origin)
  
   961         {
  
   962             if (IsSelected())
  
   963             {
  
   964                 const Brush& selectedBrush = view->ItemSelectedBrush();
  
   965                 Rect rect(location, size);
  
   966                 auto result = graphics.FillRectangle(selectedBrush, rect);
  
   967                 if (result.Error())
  
   968                 {
  
   969                     return Result<bool>(ErrorId(result.GetErrorId()));
  
   970                 }
  
   971             }
  
   972             PointF itemOrigin = origin;
  
   973             int imageSpace = 0;
  
   974             auto result = DrawImage(graphics, itemOrigin, imageSpace);
  
   975             if (result.Error())
  
   976             {
  
   977                 return Result<bool>(ErrorId(result.GetErrorId()));
  
   978             }
  
   979             for (int index = 0; index < view->ColumnCount(); ++index;)
  
   980             {
  
   981                 int imgSpc = 0;
  
   982                 if (index == 0)
  
   983                 {
  
   984                     imgSpc = imageSpace;
  
   985                 }
  
   986                 imgSpc = imageSpace;
  
   987                 bool clipped = false;
  
   988                 Region prevClip;
  
   989                 if (index < textWidths.Count())
  
   990                 {
  
   991                     auto getColumnResult = view->GetColumn(index);
  
   992                     if (getColumnResult.Error())
  
   993                     {
  
   994                         return Result<bool>(ErrorId(getColumnResult.GetErrorId()));
  
   995                     }
  
   996                     ListViewColumn* column = getColumnResult.Value();
  
   997                     if (textWidths[index] > column->Width())
  
   998                     {
  
   999                         auto clipResult = graphics.GetClip();
  
  1000                         if (clipResult.Error())
  
  1001                         {
  
  1002                             return Result<bool>(ErrorId(clipResult.GetErrorId()));
  
  1003                         }
  
  1004                         prevClip = clipResult.Value();
  
  1005                         clipped = true;
  
  1006                         auto columnResult = view->GetColumn(index);
  
  1007                         if (columnResult.Error())
  
  1008                         {
  
  1009                             return Result<bool>(ErrorId(columnResult.GetErrorId()));
  
  1010                         }
  
  1011                         ListViewColumn* column = columnResult.Value();
  
  1012                         Size itemSize(Size(cast<int>(column->Width() - view->EllipsisWidth() - imgSpc), cast<int>(view->TextHeight())));
  
  1013                         Rect clip(Point(cast<int>(itemOrigin.x), cast<int>(itemOrigin.y)), itemSize);
  
  1014                         auto setClipResult = graphics.SetClip(clip);
  
  1015                         if (setClipResult.Error())
  
  1016                         {
  
  1017                             return Result<bool>(ErrorId(setClipResult.GetErrorId()));
  
  1018                         }
  
  1019                     }
  
  1020                 }
  
  1021                 const Brush* brush = view->ItemTextBrush();
  
  1022                 if (GetState() == State.disabled)
  
  1023                 {
  
  1024                     brush = view->DisabledItemTextBrush();
  
  1025                 }
  
  1026                 auto columnValueResult = GetColumnValue(index);
  
  1027                 if (columnValueResult.Error())
  
  1028                 {
  
  1029                     return Result<bool>(ErrorId(columnValueResult.GetErrorId()));
  
  1030                 }
  
  1031                 string columnValue = Rvalue(columnValueResult.Value());
  
  1032                 auto result = graphics.DrawString(columnValue, view->GetFont(), itemOrigin, *brush);
  
  1033                 if (result.Error())
  
  1034                 {
  
  1035                     return Result<bool>(ErrorId(result.GetErrorId()));
  
  1036                 }
  
  1037                 auto columnResult = view->GetColumn(index);
  
  1038                 if (columnResult.Error())
  
  1039                 {
  
  1040                     return Result<bool>(ErrorId(columnResult.GetErrorId()));
  
  1041                 }
  
  1042                 ListViewColumn* column = columnResult.Value();
  
  1043                 itemOrigin.x = itemOrigin.x + column->Width();
  
  1044                 if (clipped)
  
  1045                 {
  
  1046                     auto setClipResult = graphics.SetClip(prevClip);
  
  1047                     if (setClipResult.Error())
  
  1048                     {
  
  1049                         return Result<bool>(ErrorId(setClipResult.GetErrorId()));
  
  1050                     }
  
  1051                     PointF ellipsisOrigin(itemOrigin.x - view->EllipsisWidth() - imgSpc, itemOrigin.y);
  
  1052                     auto result = graphics.DrawString("...", view->GetFont(), ellipsisOrigin, *brush);
  
  1053                     if (result.Error())
  
  1054                     {
  
  1055                         return Result<bool>(ErrorId(result.GetErrorId()));
  
  1056                     }
  
  1057                 }
  
  1058                 itemOrigin.x = itemOrigin.x + view->ColumnDividerPadding().Horizontal() + view->ColumnDividerWidth() - imgSpc;
  
  1059                 itemOrigin.x = itemOrigin.x + view->ItemColumnPadding().Horizontal();
  
  1060             }
  
  1061             return Result<bool>(true);
  
  1062         }
  
  1063         [nodiscard]
  
  1064         public Result<bool> Measure(Graphics& graphics)
  
  1065         {
  
  1066             float width = 0;
  
  1067             float height = 0;
  
  1068             Bitmap* image = null;
  
  1069             ImageList* imageList = view->GetImageList();
  
  1070             if (imageList != null)
  
  1071             {
  
  1072                 if (GetState() == State.enabled)
  
  1073                 {
  
  1074                     image = imageList->GetImage(imageIndex);
  
  1075                 }
  
  1076                 else
  
  1077                 {
  
  1078                     image = imageList->GetImage(disabledImageIndex);
  
  1079                 }
  
  1080             }
  
  1081             if (image != null)
  
  1082             {
  
  1083                 int imageWidth = cast<int>(image->GetWidth());
  
  1084                 int imageHeight = cast<int>(image->GetHeight());
  
  1085                 Padding padding = view->ImagePadding();
  
  1086                 if (view->ColumnCount() > 0)
  
  1087                 {
  
  1088                     auto columnResult = view->GetColumn(0);
  
  1089                     if (columnResult.Error())
  
  1090                     {
  
  1091                         return Result<bool>(ErrorId(columnResult.GetErrorId()));
  
  1092                     }
  
  1093                     ListViewColumn* firstColumn = columnResult.Value();
  
  1094                     firstColumn->SetMinWidth(Max(firstColumn->MinWidth(), cast<int>(imageWidth + padding.Horizontal() + view->EllipsisWidth() + 0.500000f)));
  
  1095                 }
  
  1096                 height = imageHeight + padding.Vertical();
  
  1097             }
  
  1098             for (int index = 0; index < view->ColumnCount(); ++index;)
  
  1099             {
  
  1100                 auto columnResult = view->GetColumn(index);
  
  1101                 if (columnResult.Error())
  
  1102                 {
  
  1103                     return Result<bool>(ErrorId(columnResult.GetErrorId()));
  
  1104                 }
  
  1105                 ListViewColumn* column = columnResult.Value();
  
  1106                 width = width + column->Width();
  
  1107                 width = width + view->ColumnDividerWidth() + view->ColumnDividerPadding().Horizontal();
  
  1108                 height = Max(height, view->TextHeight());
  
  1109                 column->SetMinWidth(Max(column->MinWidth(), cast<int>(view->EllipsisWidth() + 0.500000f)));
  
  1110             }
  
  1111             width = width + view->ItemPadding().Horizontal();
  
  1112             size = Size(cast<int>(width + 0.500000f), cast<int>(height + 0.500000f));
  
  1113             textWidths.Clear();
  
  1114             for (const string& columnValue : columnValues)
  
  1115             {
  
  1116                 auto measureResult = graphics.MeasureStringRectF(columnValue, view->GetFont(), PointF(0, 0), view->GetStringFormat());
  
  1117                 if (measureResult.Error())
  
  1118                 {
  
  1119                     return Result<bool>(ErrorId(measureResult.GetErrorId()));
  
  1120                 }
  
  1121                 RectF r = measureResult.Value();
  
  1122                 textWidths.Add(r.size.w);
  
  1123             }
  
  1124             return Result<bool>(true);
  
  1125         }
  
  1126         public inline const Point& Location() const
  
  1127         {
  
  1128             return location;
  
  1129         }
  
  1130         public void SetLocation(const Point& location_)
  
  1131         {
  
  1132             location = location_;
  
  1133         }
  
  1134         public inline const Size& GetSize() const
  
  1135         {
  
  1136             return size;
  
  1137         }
  
  1138         public inline bool GetFlag(Flags flag) const
  
  1139         {
  
  1140             return (flags & flag) != Flags.none;
  
  1141         }
  
  1142         public inline void SetFlag(Flags flag)
  
  1143         {
  
  1144             flags = cast<Flags>(flags | flag);
  
  1145         }
  
  1146         public inline void ResetFlag(Flags flag)
  
  1147         {
  
  1148             flags = cast<Flags>(flags & ~flag);
  
  1149         }
  
  1150         public inline bool IsSelected() const
  
  1151         {
  
  1152             return GetFlag(Flags.selected);
  
  1153         }
  
  1154         [nodiscard]
  
  1155         public Result<bool> SetSelected()
  
  1156         {
  
  1157             if (!IsSelected())
  
  1158             {
  
  1159                 SetFlag(Flags.selected);
  
  1160                 auto result = view->Invalidate();
  
  1161                 if (result.Error()) return result;
  
  1162             }
  
  1163             return Result<bool>(true);
  
  1164         }
  
  1165         [nodiscard]
  
  1166         public Result<bool> ResetSelected()
  
  1167         {
  
  1168             if (IsSelected())
  
  1169             {
  
  1170                 ResetFlag(Flags.selected);
  
  1171                 auto result = view->Invalidate();
  
  1172                 if (result.Error()) return result;
  
  1173             }
  
  1174             return Result<bool>(true);
  
  1175         }
  
  1176         public State GetState() const
  
  1177         {
  
  1178             if (GetFlag(Flags.disabled))
  
  1179             {
  
  1180                 return State.disabled;
  
  1181             }
  
  1182             else
  
  1183             {
  
  1184                 return State.enabled;
  
  1185             }
  
  1186         }
  
  1187         [nodiscard]
  
  1188         public Result<bool> SetState(State state)
  
  1189         {
  
  1190             if (state != GetState())
  
  1191             {
  
  1192                 if (state == State.disabled)
  
  1193                 {
  
  1194                     SetFlag(Flags.disabled);
  
  1195                 }
  
  1196                 else
  
  1197                 {
  
  1198                     ResetFlag(Flags.disabled);
  
  1199                 }
  
  1200                 auto result = view->Invalidate();
  
  1201                 if (result.Error()) return result;
  
  1202             }
  
  1203             return Result<bool>(true);
  
  1204         }
  
  1205         public inline ListView* View() const
  
  1206         {
  
  1207             return view;
  
  1208         }
  
  1209         public inline void* Data() const
  
  1210         {
  
  1211             return data;
  
  1212         }
  
  1213         public void SetData(void* data_)
  
  1214         {
  
  1215             data = data_;
  
  1216         }
  
  1217         public inline int ImageIndex() const
  
  1218         {
  
  1219             return imageIndex;
  
  1220         }
  
  1221         public void SetImageIndex(int imageIndex_)
  
  1222         {
  
  1223             imageIndex = imageIndex_;
  
  1224         }
  
  1225         public inline int DisabledImageIndex() const
  
  1226         {
  
  1227             return disabledImageIndex;
  
  1228         }
  
  1229         public void SetDisabledImageIndex(int disabledImageIndex_)
  
  1230         {
  
  1231             disabledImageIndex = disabledImageIndex_;
  
  1232         }
  
  1233         private Result<bool> DrawImage(Graphics& graphics, PointF& origin, int& imageSpace)
  
  1234         {
  
  1235             imageSpace = 0;
  
  1236             Bitmap* image = null;
  
  1237             ImageList* imageList = view->GetImageList();
  
  1238             if (imageList != null)
  
  1239             {
  
  1240                 if (GetState() == State.enabled)
  
  1241                 {
  
  1242                     image = imageList->GetImage(imageIndex);
  
  1243                 }
  
  1244                 else
  
  1245                 {
  
  1246                     image = imageList->GetImage(disabledImageIndex);
  
  1247                 }
  
  1248             }
  
  1249             if (image != null)
  
  1250             {
  
  1251                 int imageWidth = cast<int>(image->GetWidth());
  
  1252                 int imageHeight = cast<int>(image->GetHeight());
  
  1253                 Padding padding = view->ImagePadding();
  
  1254                 Point imageLoc = Point(cast<int>(origin.x), cast<int>(origin.y));
  
  1255                 imageLoc.x = imageLoc.x + padding.left;
  
  1256                 imageLoc.y = imageLoc.y + padding.top;
  
  1257                 Rect r(imageLoc, Size(imageWidth + padding.Horizontal(), imageHeight + padding.Vertical()));
  
  1258                 ImageAttributes attributes;
  
  1259                 if (attributes.Error())
  
  1260                 {
  
  1261                     return Result<bool>(ErrorId(attributes.GetErrorId()));
  
  1262                 }
  
  1263                 auto setResult = attributes.SetColorKey(Color.DefaultBitmapTransparent(), Color.DefaultBitmapTransparent(), ColorAdjustType.default_);
  
  1264                 if (setResult.Error())
  
  1265                 {
  
  1266                     return Result<bool>(ErrorId(setResult.GetErrorId()));
  
  1267                 }
  
  1268                 auto drawResult = graphics.DrawImage(*image, r, 0, 0, imageWidth + padding.Horizontal(), imageHeight + padding.Vertical(), Unit.pixel, attributes);
  
  1269                 if (drawResult.Error())
  
  1270                 {
  
  1271                     return Result<bool>(ErrorId(drawResult.GetErrorId()));
  
  1272                 }
  
  1273                 imageSpace = imageWidth + padding.Horizontal();
  
  1274                 origin.x = origin.x + imageSpace;
  
  1275             }
  
  1276             return Result<bool>(true);
  
  1277         }
  
  1278         private Flags flags;
  
  1279         private Point location;
  
  1280         private Size size;
  
  1281         private ListView* view;
  
  1282         private int imageIndex;
  
  1283         private int disabledImageIndex;
  
  1284         private void* data;
  
  1285         private List<string> columnValues;
  
  1286         private List<float> textWidths;
  
  1287     }