ListView.cs 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004-2005 Novell, Inc. (http://www.novell.com)
  21. //
  22. // Authors:
  23. // Ravindra Kumar ([email protected])
  24. // Jordi Mas i Hernandez, [email protected]
  25. //
  26. // TODO:
  27. // - Item text editing
  28. // - Column resizing/reodering
  29. // - Feedback for item activation, change in cursor types as mouse moves.
  30. // - HideSelection
  31. // - LabelEdit
  32. // - Manual column resizing
  33. // - Drag and drop
  34. // NOT COMPLETE
  35. using System.Collections;
  36. using System.ComponentModel;
  37. using System.ComponentModel.Design;
  38. using System.Drawing;
  39. using System.Runtime.InteropServices;
  40. namespace System.Windows.Forms
  41. {
  42. [DefaultEvent ("SelectedIndexChanged")]
  43. [DefaultProperty ("Items")]
  44. [Designer ("System.Windows.Forms.Design.ListViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  45. public class ListView : Control
  46. {
  47. private ItemActivation activation = ItemActivation.Standard;
  48. private ListViewAlignment alignment = ListViewAlignment.Top;
  49. private bool allow_column_reorder = false;
  50. private bool auto_arrange = true;
  51. private bool check_boxes = false;
  52. private CheckedIndexCollection checked_indices;
  53. private CheckedListViewItemCollection checked_items;
  54. private ColumnHeader clicked_column;
  55. private ListViewItem clicked_item;
  56. private ListViewItem last_clicked_item;
  57. private ColumnHeaderCollection columns;
  58. private bool ctrl_pressed;
  59. private bool shift_pressed;
  60. internal ListViewItem focused_item;
  61. private bool full_row_select = false;
  62. private bool grid_lines = false;
  63. private ColumnHeaderStyle header_style = ColumnHeaderStyle.Clickable;
  64. private bool hide_selection = true;
  65. private bool hover_selection = false;
  66. private IComparer item_sorter;
  67. private ListViewItemCollection items;
  68. private bool label_edit = false;
  69. private bool label_wrap = true;
  70. private bool multiselect = true;
  71. private bool scrollable = true;
  72. private SelectedIndexCollection selected_indices;
  73. private SelectedListViewItemCollection selected_items;
  74. private SortOrder sort_order = SortOrder.None;
  75. private ImageList state_image_list;
  76. private bool updating = false;
  77. private View view = View.LargeIcon;
  78. private int layout_wd; // We might draw more than our client area
  79. private int layout_ht; // therefore we need to have these two.
  80. //private TextBox editor; // Used for editing an item text
  81. internal ScrollBar h_scroll; // used for scrolling horizontally
  82. internal ScrollBar v_scroll; // used for scrolling vertically
  83. internal int h_marker; // Position markers for scrolling
  84. internal int v_marker;
  85. internal Rectangle client_area; // ClientRectangle - scrollbars
  86. // internal variables
  87. internal ImageList large_image_list;
  88. internal ImageList small_image_list;
  89. internal Size text_size = Size.Empty;
  90. #region Events
  91. public event LabelEditEventHandler AfterLabelEdit;
  92. [Browsable (false)]
  93. [EditorBrowsable (EditorBrowsableState.Never)]
  94. public new event EventHandler BackgroundImageChanged;
  95. public event LabelEditEventHandler BeforeLabelEdit;
  96. public event ColumnClickEventHandler ColumnClick;
  97. public event EventHandler ItemActivate;
  98. public event ItemCheckEventHandler ItemCheck;
  99. public event ItemDragEventHandler ItemDrag;
  100. [Browsable (false)]
  101. [EditorBrowsable (EditorBrowsableState.Never)]
  102. public new event PaintEventHandler Paint;
  103. public event EventHandler SelectedIndexChanged;
  104. [Browsable (false)]
  105. [EditorBrowsable (EditorBrowsableState.Never)]
  106. public new event EventHandler TextChanged;
  107. #endregion // Events
  108. #region Public Constructors
  109. public ListView ()
  110. {
  111. background_color = ThemeEngine.Current.ColorWindow;
  112. checked_indices = new CheckedIndexCollection (this);
  113. checked_items = new CheckedListViewItemCollection (this);
  114. columns = new ColumnHeaderCollection (this);
  115. foreground_color = SystemColors.WindowText;
  116. items = new ListViewItemCollection (this);
  117. selected_indices = new SelectedIndexCollection (this);
  118. selected_items = new SelectedListViewItemCollection (this);
  119. border_style = BorderStyle.Fixed3D;
  120. // we are mostly scrollable
  121. h_scroll = new HScrollBar ();
  122. v_scroll = new VScrollBar ();
  123. h_marker = v_marker = 0;
  124. // scroll bars are disabled initially
  125. h_scroll.Visible = false;
  126. h_scroll.ValueChanged += new EventHandler(HorizontalScroller);
  127. v_scroll.Visible = false;
  128. v_scroll.ValueChanged += new EventHandler(VerticalScroller);
  129. // event handlers
  130. base.DoubleClick += new EventHandler(ListView_DoubleClick);
  131. base.KeyDown += new KeyEventHandler(ListView_KeyDown);
  132. base.KeyUp += new KeyEventHandler(ListView_KeyUp);
  133. base.MouseDown += new MouseEventHandler(ListView_MouseDown);
  134. base.MouseHover += new EventHandler(ListView_MouseHover);
  135. base.MouseUp += new MouseEventHandler(ListView_MouseUp);
  136. base.MouseMove += new MouseEventHandler(ListView_MouseMove);
  137. base.Paint += new PaintEventHandler (ListView_Paint);
  138. SizeChanged += new EventHandler (ListView_SizeChanged);
  139. this.SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick, false);
  140. }
  141. #endregion // Public Constructors
  142. #region Private Internal Properties
  143. internal Size CheckBoxSize {
  144. get {
  145. if (this.check_boxes) {
  146. if (this.state_image_list != null)
  147. return this.state_image_list.ImageSize;
  148. else
  149. return ThemeEngine.Current.ListViewCheckBoxSize;
  150. }
  151. return Size.Empty;
  152. }
  153. }
  154. internal bool CanMultiselect {
  155. get {
  156. if (this.multiselect &&
  157. (this.ctrl_pressed || this.shift_pressed))
  158. return true;
  159. else
  160. return false;
  161. }
  162. }
  163. #endregion // Private Internal Properties
  164. #region Protected Properties
  165. protected override CreateParams CreateParams {
  166. get { return base.CreateParams; }
  167. }
  168. protected override Size DefaultSize {
  169. get { return ThemeEngine.Current.ListViewDefaultSize; }
  170. }
  171. #endregion // Protected Properties
  172. #region Public Instance Properties
  173. [DefaultValue (ItemActivation.Standard)]
  174. public ItemActivation Activation {
  175. get { return activation; }
  176. set {
  177. if (value != ItemActivation.Standard && value != ItemActivation.OneClick &&
  178. value != ItemActivation.TwoClick) {
  179. throw new InvalidEnumArgumentException (string.Format
  180. ("Enum argument value '{0}' is not valid for Activation", value));
  181. }
  182. activation = value;
  183. }
  184. }
  185. [DefaultValue (ListViewAlignment.Top)]
  186. [Localizable (true)]
  187. public ListViewAlignment Alignment {
  188. get { return alignment; }
  189. set {
  190. if (value != ListViewAlignment.Default && value != ListViewAlignment.Left &&
  191. value != ListViewAlignment.SnapToGrid && value != ListViewAlignment.Top) {
  192. throw new InvalidEnumArgumentException (string.Format
  193. ("Enum argument value '{0}' is not valid for Alignment", value));
  194. }
  195. if (this.alignment != value) {
  196. alignment = value;
  197. // alignment does not matter in Details/List views
  198. if (this.view == View.LargeIcon ||
  199. this.View == View.SmallIcon)
  200. this.Redraw (true);
  201. }
  202. }
  203. }
  204. [DefaultValue (false)]
  205. public bool AllowColumnReorder {
  206. get { return allow_column_reorder; }
  207. set {
  208. if (this.allow_column_reorder != value) {
  209. allow_column_reorder = value;
  210. // column reorder does not matter in Details view
  211. if (this.view != View.Details)
  212. this.Redraw (true);
  213. }
  214. }
  215. }
  216. [DefaultValue (true)]
  217. public bool AutoArrange {
  218. get { return auto_arrange; }
  219. set {
  220. if (auto_arrange != value) {
  221. auto_arrange = value;
  222. // autoarrange does not matter in Details/List views
  223. if (this.view == View.LargeIcon || this.View == View.SmallIcon)
  224. this.Redraw (true);
  225. }
  226. }
  227. }
  228. public override Color BackColor {
  229. get {
  230. if (background_color.IsEmpty)
  231. return ThemeEngine.Current.ColorWindow;
  232. else
  233. return background_color;
  234. }
  235. set { background_color = value; }
  236. }
  237. [Browsable (false)]
  238. [EditorBrowsable (EditorBrowsableState.Never)]
  239. public override Image BackgroundImage {
  240. get { return background_image; }
  241. set {
  242. if (value == background_image)
  243. return;
  244. background_image = value;
  245. if (BackgroundImageChanged != null)
  246. BackgroundImageChanged (this, new EventArgs ());
  247. }
  248. }
  249. [DefaultValue (BorderStyle.Fixed3D)]
  250. [DispId (-504)]
  251. public BorderStyle BorderStyle {
  252. get { return InternalBorderStyle; }
  253. set { InternalBorderStyle = value; }
  254. }
  255. [DefaultValue (false)]
  256. public bool CheckBoxes {
  257. get { return check_boxes; }
  258. set {
  259. if (check_boxes != value) {
  260. check_boxes = value;
  261. this.Redraw (true);
  262. }
  263. }
  264. }
  265. [Browsable (false)]
  266. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  267. public CheckedIndexCollection CheckedIndices {
  268. get { return checked_indices; }
  269. }
  270. [Browsable (false)]
  271. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  272. public CheckedListViewItemCollection CheckedItems {
  273. get { return checked_items; }
  274. }
  275. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  276. [Localizable (true)]
  277. [MergableProperty (false)]
  278. public ColumnHeaderCollection Columns {
  279. get { return columns; }
  280. }
  281. [Browsable (false)]
  282. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  283. public ListViewItem FocusedItem {
  284. get { return focused_item; }
  285. }
  286. public override Color ForeColor {
  287. get {
  288. if (foreground_color.IsEmpty)
  289. return ThemeEngine.Current.ColorWindowText;
  290. else
  291. return foreground_color;
  292. }
  293. set { foreground_color = value; }
  294. }
  295. [DefaultValue (false)]
  296. public bool FullRowSelect {
  297. get { return full_row_select; }
  298. set { full_row_select = value; }
  299. }
  300. [DefaultValue (false)]
  301. public bool GridLines {
  302. get { return grid_lines; }
  303. set {
  304. if (grid_lines != value) {
  305. grid_lines = value;
  306. this.Redraw (false);
  307. }
  308. }
  309. }
  310. [DefaultValue (ColumnHeaderStyle.Clickable)]
  311. public ColumnHeaderStyle HeaderStyle {
  312. get { return header_style; }
  313. set {
  314. if (value != ColumnHeaderStyle.Clickable && value != ColumnHeaderStyle.Nonclickable &&
  315. value != ColumnHeaderStyle.None) {
  316. throw new InvalidEnumArgumentException (string.Format
  317. ("Enum argument value '{0}' is not valid for ColumnHeaderStyle", value));
  318. }
  319. if (header_style != value) {
  320. header_style = value;
  321. // header style matters only in Details view
  322. if (this.view == View.Details)
  323. this.Redraw (false);
  324. }
  325. }
  326. }
  327. [DefaultValue (true)]
  328. public bool HideSelection {
  329. get { return hide_selection; }
  330. set {
  331. if (hide_selection != value) {
  332. hide_selection = value;
  333. this.Redraw (false);
  334. }
  335. }
  336. }
  337. [DefaultValue (false)]
  338. public bool HoverSelection {
  339. get { return hover_selection; }
  340. set { hover_selection = value; }
  341. }
  342. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  343. [Localizable (true)]
  344. [MergableProperty (false)]
  345. public ListViewItemCollection Items {
  346. get { return items; }
  347. }
  348. [DefaultValue (false)]
  349. public bool LabelEdit {
  350. get { return label_edit; }
  351. set { label_edit = value; }
  352. }
  353. [DefaultValue (true)]
  354. [Localizable (true)]
  355. public bool LabelWrap {
  356. get { return label_wrap; }
  357. set {
  358. if (label_wrap != value) {
  359. label_wrap = value;
  360. this.Redraw (true);
  361. }
  362. }
  363. }
  364. [DefaultValue (null)]
  365. public ImageList LargeImageList {
  366. get { return large_image_list; }
  367. set {
  368. large_image_list = value;
  369. this.Redraw (true);
  370. }
  371. }
  372. [Browsable (false)]
  373. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  374. public IComparer ListViewItemSorter {
  375. get { return item_sorter; }
  376. set { item_sorter = value; }
  377. }
  378. [DefaultValue (true)]
  379. public bool MultiSelect {
  380. get { return multiselect; }
  381. set { multiselect = value; }
  382. }
  383. [DefaultValue (true)]
  384. public bool Scrollable {
  385. get { return scrollable; }
  386. set {
  387. if (scrollable != value) {
  388. scrollable = value;
  389. this.Redraw (true);
  390. }
  391. }
  392. }
  393. [Browsable (false)]
  394. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  395. public SelectedIndexCollection SelectedIndices {
  396. get { return selected_indices; }
  397. }
  398. [Browsable (false)]
  399. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  400. public SelectedListViewItemCollection SelectedItems {
  401. get { return selected_items; }
  402. }
  403. [DefaultValue (null)]
  404. public ImageList SmallImageList {
  405. get { return small_image_list; }
  406. set {
  407. small_image_list = value;
  408. this.Redraw (true);
  409. }
  410. }
  411. [DefaultValue (SortOrder.None)]
  412. public SortOrder Sorting {
  413. get { return sort_order; }
  414. set {
  415. if (value != SortOrder.Ascending && value != SortOrder.Descending &&
  416. value != SortOrder.None) {
  417. throw new InvalidEnumArgumentException (string.Format
  418. ("Enum argument value '{0}' is not valid for Sorting", value));
  419. }
  420. if (sort_order != value) {
  421. sort_order = value;
  422. this.Redraw (false);
  423. }
  424. }
  425. }
  426. [DefaultValue (null)]
  427. public ImageList StateImageList {
  428. get { return state_image_list; }
  429. set {
  430. state_image_list = value;
  431. this.Redraw (true);
  432. }
  433. }
  434. [Bindable (false)]
  435. [Browsable (false)]
  436. [EditorBrowsable (EditorBrowsableState.Never)]
  437. public override string Text {
  438. get { return text; }
  439. set {
  440. if (value == text)
  441. return;
  442. text = value;
  443. this.Redraw (true);
  444. if (TextChanged != null)
  445. TextChanged (this, new EventArgs ());
  446. }
  447. }
  448. [Browsable (false)]
  449. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  450. public ListViewItem TopItem {
  451. get {
  452. // there is no item
  453. if (this.items.Count == 0)
  454. return null;
  455. // if contents are not scrolled
  456. // it is the first item
  457. else if (h_marker == 0 && v_marker == 0)
  458. return this.items [0];
  459. // do a hit test for the scrolled position
  460. else {
  461. foreach (ListViewItem item in this.items) {
  462. if (item.EntireRect.X >= h_marker && item.EntireRect.Y >= v_marker)
  463. return item;
  464. }
  465. return null;
  466. }
  467. }
  468. }
  469. [DefaultValue (View.LargeIcon)]
  470. public View View {
  471. get { return view; }
  472. set {
  473. if (value != View.Details && value != View.LargeIcon &&
  474. value != View.List && value != View.SmallIcon ) {
  475. throw new InvalidEnumArgumentException (string.Format
  476. ("Enum argument value '{0}' is not valid for View", value));
  477. }
  478. if (view != value) {
  479. view = value;
  480. Redraw (true);
  481. }
  482. }
  483. }
  484. #endregion // Public Instance Properties
  485. #region Internal Methods Properties
  486. public int FirstVisibleIndex {
  487. get {
  488. // there is no item
  489. if (this.items.Count == 0)
  490. return 0;
  491. if (h_marker == 0 && v_marker == 0)
  492. return 0;
  493. foreach (ListViewItem item in this.items) {
  494. if (item.EntireRect.X + item.EntireRect.Width >= h_marker
  495. && item.EntireRect.Y + item.EntireRect.Height >= v_marker)
  496. return item.Index;
  497. }
  498. return 0;
  499. }
  500. }
  501. internal int LastItemIndex {
  502. get {
  503. for (int i = FirstVisibleIndex; i < Items.Count; i++) {
  504. if (Items[i].EntireRect.Y > v_marker + ClientRectangle.Bottom)
  505. return i -1;
  506. }
  507. return Items.Count - 1;
  508. }
  509. }
  510. internal int TotalWidth {
  511. get { return Math.Max (this.Width, this.layout_wd); }
  512. }
  513. internal int TotalHeight {
  514. get { return Math.Max (this.Height, this.layout_ht); }
  515. }
  516. internal void Redraw (bool recalculate)
  517. {
  518. // Avoid calculations when control is being updated
  519. if (this.updating)
  520. return;
  521. if (recalculate)
  522. CalculateListView (this.alignment);
  523. Refresh ();
  524. }
  525. internal Size GetChildColumnSize (int index)
  526. {
  527. Size ret_size = Size.Empty;
  528. ColumnHeader col = this.columns [index];
  529. if (col.Width == -2) { // autosize = max(items, columnheader)
  530. Size size = Size.Ceiling (this.DeviceContext.MeasureString
  531. (col.Text, this.Font));
  532. ret_size = BiggestItem (index);
  533. if (size.Width > ret_size.Width)
  534. ret_size = size;
  535. }
  536. else { // -1 and all the values < -2 are put under one category
  537. ret_size = BiggestItem (index);
  538. // fall back to empty columns' width if no subitem is available for a column
  539. if (ret_size.IsEmpty) {
  540. ret_size.Width = ThemeEngine.Current.ListViewEmptyColumnWidth;
  541. if (col.Text.Length > 0)
  542. ret_size.Height = Size.Ceiling (this.DeviceContext.MeasureString
  543. (col.Text, this.Font)).Height;
  544. else
  545. ret_size.Height = this.Font.Height;
  546. }
  547. }
  548. // adjust the size for icon and checkbox for 0th column
  549. if (index == 0) {
  550. ret_size.Width += (this.CheckBoxSize.Width + 4);
  551. if (this.small_image_list != null)
  552. ret_size.Width += this.small_image_list.ImageSize.Width;
  553. }
  554. return ret_size;
  555. }
  556. // Returns the size of biggest item text in a column.
  557. private Size BiggestItem (int col)
  558. {
  559. Size temp = Size.Empty;
  560. Size ret_size = Size.Empty;
  561. // 0th column holds the item text, we check the size of
  562. // the various subitems falling in that column and get
  563. // the biggest one's size.
  564. foreach (ListViewItem item in items) {
  565. if (col >= item.SubItems.Count)
  566. continue;
  567. temp = Size.Ceiling (this.DeviceContext.MeasureString
  568. (item.SubItems [col].Text, this.Font));
  569. if (temp.Width > ret_size.Width)
  570. ret_size = temp;
  571. }
  572. // adjustment for space
  573. if (!ret_size.IsEmpty)
  574. ret_size.Width += 4;
  575. return ret_size;
  576. }
  577. // Sets the size of the biggest item text as per the view
  578. private void CalcTextSize ()
  579. {
  580. // clear the old value
  581. text_size = Size.Empty;
  582. if (items.Count == 0)
  583. return;
  584. text_size = BiggestItem (0);
  585. if (view == View.LargeIcon && this.label_wrap) {
  586. Size temp = Size.Empty;
  587. if (this.check_boxes)
  588. temp.Width += 2 * this.CheckBoxSize.Width;
  589. if (large_image_list != null)
  590. temp.Width += large_image_list.ImageSize.Width;
  591. if (temp.Width == 0)
  592. temp.Width = 43;
  593. // wrapping is done for two lines only
  594. if (text_size.Width > temp.Width) {
  595. text_size.Width = temp.Width;
  596. text_size.Height *= 2;
  597. }
  598. }
  599. else if (view == View.List) {
  600. // in list view max text shown in determined by the
  601. // control width, even if scolling is enabled.
  602. int max_wd = this.Width - (this.CheckBoxSize.Width - 2);
  603. if (this.small_image_list != null)
  604. max_wd -= this.small_image_list.ImageSize.Width;
  605. if (text_size.Width > max_wd)
  606. text_size.Width = max_wd;
  607. }
  608. // we do the default settings, if we have got 0's
  609. if (text_size.Height <= 0)
  610. text_size.Height = this.Font.Height;
  611. if (text_size.Width <= 0)
  612. text_size.Width = this.Width;
  613. // little adjustment
  614. text_size.Width += 4;
  615. text_size.Height += 2;
  616. }
  617. private void CalculateScrollBars ()
  618. {
  619. client_area = ClientRectangle;
  620. if (!this.scrollable || this.items.Count <= 0) {
  621. h_scroll.Visible = false;
  622. v_scroll.Visible = false;
  623. return;
  624. }
  625. // making a scroll bar visible might make
  626. // other scroll bar visible
  627. if (layout_wd > client_area.Right) {
  628. h_scroll.Visible = true;
  629. if ((layout_ht + h_scroll.Height) > client_area.Bottom) {
  630. v_scroll.Visible = true;
  631. }
  632. } else if (layout_ht > client_area.Bottom) {
  633. v_scroll.Visible = true;
  634. if ((layout_wd + v_scroll.Width) > client_area.Right)
  635. h_scroll.Visible = true;
  636. }
  637. if (h_scroll.Visible) {
  638. h_scroll.Location = new Point (client_area.X, client_area.Bottom - h_scroll.Height);
  639. h_scroll.Minimum = 0;
  640. // if v_scroll is visible, adjust the maximum of the
  641. // h_scroll to account for the width of v_scroll
  642. if (v_scroll.Visible) {
  643. h_scroll.Maximum = layout_wd + v_scroll.Width;
  644. h_scroll.Width = client_area.Width - v_scroll.Width;
  645. }
  646. else {
  647. h_scroll.Maximum = layout_wd;
  648. h_scroll.Width = client_area.Width;
  649. }
  650. h_scroll.LargeChange = client_area.Width;
  651. h_scroll.SmallChange = Font.Height;
  652. client_area.Height -= h_scroll.Height;
  653. }
  654. // vertical scrollbar
  655. if (v_scroll.Visible) {
  656. v_scroll.Location = new Point (client_area.Right - v_scroll.Width, client_area.Y);
  657. v_scroll.Minimum = 0;
  658. // if h_scroll is visible, adjust the maximum of the
  659. // v_scroll to account for the height of h_scroll
  660. if (h_scroll.Visible) {
  661. v_scroll.Maximum = layout_ht + h_scroll.Height;
  662. v_scroll.Height = client_area.Height; // - h_scroll.Height already done
  663. } else {
  664. v_scroll.Maximum = layout_ht;
  665. v_scroll.Height = client_area.Height;
  666. }
  667. v_scroll.LargeChange = client_area.Height;
  668. v_scroll.SmallChange = Font.Height;
  669. client_area.Width -= v_scroll.Width;
  670. }
  671. }
  672. // Sets the location of every item on
  673. // the ListView as per the view
  674. private void CalculateListView (ListViewAlignment align)
  675. {
  676. int current_pos_x = 0; // our x-position marker
  677. int current_pos_y = 0; // our y-position marker
  678. int item_ht;
  679. int item_wd;
  680. int max; // max x_pos or y_pos depending on the alignment
  681. int current = 0; // current row or column
  682. int vertical_spacing = ThemeEngine.Current.ListViewVerticalSpacing;
  683. int horizontal_spacing = ThemeEngine.Current.ListViewHorizontalSpacing;
  684. CalcTextSize ();
  685. switch (view) {
  686. case View.Details:
  687. // ColumnHeaders are not drawn if headerstyle is none
  688. int ht = (this.header_style == ColumnHeaderStyle.None) ?
  689. 0 : this.Font.Height + 3;
  690. if (columns.Count > 0) {
  691. foreach (ColumnHeader col in columns) {
  692. col.X = current_pos_x;
  693. col.Y = current_pos_y;
  694. col.CalcColumnHeader ();
  695. current_pos_x += col.Wd;
  696. }
  697. this.layout_wd = current_pos_x;
  698. }
  699. // set the position marker for placing items
  700. // vertically down
  701. current_pos_y = ht;
  702. if (items.Count > 0) {
  703. foreach (ListViewItem item in items) {
  704. item.location.X = 0;
  705. item.location.Y = current_pos_y;
  706. item.CalcListViewItem ();
  707. current_pos_y += item.EntireRect.Height;
  708. }
  709. this.layout_ht = current_pos_y;
  710. // some space for bottom gridline
  711. if (this.grid_lines)
  712. this.layout_ht += 2;
  713. }
  714. break;
  715. case View.SmallIcon:
  716. vertical_spacing = 0;
  717. horizontal_spacing = 0;
  718. goto case View.LargeIcon;
  719. case View.LargeIcon:
  720. if (items.Count > 0) {
  721. items [0].CalcListViewItem ();
  722. item_ht = items [0].EntireRect.Height;
  723. item_wd = items [0].EntireRect.Width;
  724. // top (default) and snaptogrid alignments are handled same way
  725. if (align == ListViewAlignment.Left) {
  726. max = client_area.Height;
  727. foreach (ListViewItem item in items) {
  728. item.location.X = current_pos_x +
  729. horizontal_spacing;
  730. item.location.Y = 0;
  731. item.CalcListViewItem ();
  732. current_pos_y += item_ht;
  733. current ++; // just to know about the last element
  734. // we just did the last item
  735. if (current == items.Count) {
  736. if (max < current_pos_y)
  737. max = current_pos_y;
  738. current_pos_x = item.EntireRect.Right;
  739. break;
  740. }
  741. else {
  742. // is there enough space for another row ?
  743. if ((current_pos_y + vertical_spacing
  744. + item_ht) <= client_area.Height)
  745. current_pos_y += vertical_spacing;
  746. else {
  747. // start another column
  748. // make current_pos_y as the
  749. // max value and reset
  750. // current_pos_y value.
  751. max = current_pos_y;
  752. current_pos_x += item_wd;
  753. current_pos_y = 0;
  754. }
  755. }
  756. }
  757. // adjust the layout dimensions
  758. this.layout_ht = max;
  759. this.layout_wd = current_pos_x;
  760. }
  761. else { // other default/top alignment
  762. max = client_area.Width;
  763. foreach (ListViewItem item in items) {
  764. item.location.X = current_pos_x +
  765. horizontal_spacing;
  766. item.location.Y = current_pos_y;
  767. item.CalcListViewItem ();
  768. current_pos_x += item_wd;
  769. current ++; // just to know about the last element
  770. // we just did the last item
  771. if (current == items.Count) {
  772. if (max < current_pos_x)
  773. max = current_pos_x;
  774. current_pos_y = item.EntireRect.Bottom;
  775. break;
  776. }
  777. else {
  778. // is there enough space for another column?
  779. if ((current_pos_x + horizontal_spacing
  780. + item_wd) <= client_area.Width)
  781. continue;
  782. else {
  783. // start another row
  784. // make current_pos_x as the
  785. // max value and reset
  786. // current_pos_x value.
  787. max = current_pos_x;
  788. current_pos_y += (item_ht +
  789. vertical_spacing);
  790. current_pos_x = 0;
  791. }
  792. }
  793. }
  794. // adjust the layout dimensions
  795. this.layout_wd = max;
  796. this.layout_ht = current_pos_y;
  797. }
  798. }
  799. break;
  800. case View.List:
  801. if (items.Count > 0) {
  802. items [0].CalcListViewItem ();
  803. item_ht = items [0].EntireRect.Height;
  804. item_wd = items [0].EntireRect.Width;
  805. max = client_area.Height / item_ht;
  806. if (max == 0)
  807. max = 1; // we draw at least one row
  808. foreach (ListViewItem item in items) {
  809. item.location.X = current_pos_x;
  810. item.location.Y = current_pos_y;
  811. item.CalcListViewItem ();
  812. current ++;
  813. if (current == max) {
  814. current_pos_x += item_wd;
  815. current_pos_y = 0;
  816. current = 0;
  817. }
  818. else
  819. current_pos_y += item_ht;
  820. }
  821. // adjust the layout dimensions
  822. this.layout_ht = max * item_ht;
  823. if (current == 0) // we have fully filled layout
  824. this.layout_wd = current_pos_x;
  825. else
  826. this.layout_wd = current_pos_x + item_wd;
  827. }
  828. break;
  829. }
  830. CalculateScrollBars ();
  831. }
  832. // Event Handlers
  833. private void ListView_DoubleClick (object sender, EventArgs e)
  834. {
  835. if (this.activation == ItemActivation.Standard
  836. && this.ItemActivate != null)
  837. this.ItemActivate (this, e);
  838. }
  839. private void ListView_KeyDown (object sender, KeyEventArgs ke)
  840. {
  841. int index = -1;
  842. if (ke.Handled || Items.Count == 0)
  843. return;
  844. ke.Handled = true;
  845. switch (ke.KeyCode) {
  846. case Keys.ControlKey:
  847. ctrl_pressed = true;
  848. break;
  849. case Keys.Down:
  850. if (focused_item != null && focused_item.Index + 1 < Items.Count) {
  851. index = focused_item.Index + 1;
  852. }
  853. break;
  854. case Keys.End:
  855. index = Items.Count - 1;
  856. break;
  857. case Keys.Home:
  858. index = 0;
  859. break;
  860. case Keys.Left:
  861. index = -1;
  862. if (focused_item != null)
  863. index = focused_item.Index;
  864. else
  865. break;
  866. if (index > 0)
  867. index -= 1;
  868. break;
  869. case Keys.Right:
  870. if (focused_item != null)
  871. index = focused_item.Index + 1;
  872. else
  873. index = 1;
  874. if (index == items.Count)
  875. index = -1;
  876. break;
  877. case Keys.ShiftKey:
  878. shift_pressed = true;
  879. break;
  880. case Keys.Up:
  881. if (focused_item != null)
  882. index = focused_item.Index;
  883. else
  884. break;
  885. if (index > 0)
  886. index--;
  887. if (index < 0) {
  888. index = -1;
  889. }
  890. break;
  891. default:
  892. ke.Handled = false;
  893. break;
  894. }
  895. if (index != -1) {
  896. items [index].Selected = true;
  897. SetFocusedItem (items [index]);
  898. EnsureVisible (index);
  899. }
  900. }
  901. private void ListView_KeyUp (object sender, KeyEventArgs ke)
  902. {
  903. if (!ke.Handled) {
  904. if (ke.KeyCode == Keys.ControlKey)
  905. this.ctrl_pressed = false;
  906. if (ke.KeyCode == Keys.ShiftKey)
  907. this.shift_pressed = false;
  908. ke.Handled = true;
  909. }
  910. }
  911. private void ListView_MouseDown (object sender, MouseEventArgs me)
  912. {
  913. if (items.Count == 0)
  914. return;
  915. Point hit = Point.Empty;
  916. if (this.HeaderStyle != ColumnHeaderStyle.None) {
  917. // take horizontal scrolling into account
  918. hit = new Point (me.X + h_marker, me.Y);
  919. // hit test on columns
  920. if (this.view == View.Details && this.columns.Count > 0) {
  921. foreach (ColumnHeader col in this.columns) {
  922. if (col.Rect.Contains (hit)) {
  923. this.clicked_column = col;
  924. this.Capture = true;
  925. break;
  926. }
  927. }
  928. if (this.clicked_column != null) {
  929. this.clicked_column.pressed = true;
  930. this.Redraw (false);
  931. return;
  932. }
  933. }
  934. }
  935. // hit test on items
  936. // we need to take scrolling into account
  937. hit = new Point (me.X + h_marker, me.Y + v_marker);
  938. foreach (ListViewItem item in this.items) {
  939. if (item.CheckRect.Contains (hit)) {
  940. CheckState curr_state = item.Checked ?
  941. CheckState.Checked : CheckState.Unchecked;
  942. if (item.Checked)
  943. item.Checked = false;
  944. else
  945. item.Checked = true;
  946. CheckState new_state = item.Checked ?
  947. CheckState.Checked : CheckState.Unchecked;
  948. this.Redraw (false);
  949. // Raise the ItemCheck event
  950. ItemCheckEventArgs ice = new ItemCheckEventArgs (item.Index,
  951. curr_state,
  952. new_state);
  953. this.OnItemCheck (ice);
  954. break;
  955. }
  956. if (this.view == View.Details &&
  957. this.FullRowSelect == false) {
  958. if (item.LabelRect.Contains (hit)) {
  959. this.clicked_item = item;
  960. break;
  961. }
  962. }
  963. else {
  964. if (item.EntireRect.Contains (hit)) {
  965. this.clicked_item = item;
  966. break;
  967. }
  968. }
  969. }
  970. // set the FocusedItem to be the current clicked_item
  971. SetFocusedItem (clicked_item);
  972. if (this.clicked_item != null) {
  973. this.clicked_item.Selected = true;
  974. // Raise the event
  975. this.OnSelectedIndexChanged (new EventArgs ());
  976. this.Redraw (false);
  977. }
  978. }
  979. private void ListView_MouseHover (object sender, EventArgs e)
  980. {
  981. // handle the hover events only when the mouse
  982. // is not captured.
  983. if (this.hover_selection == false || this.Capture)
  984. return;
  985. // hit test for the items
  986. Point hit = this.PointToClient (Control.MousePosition);
  987. ListViewItem item = this.GetItemAt (hit.X, hit.Y);
  988. if (item != null) {
  989. item.Selected = true;
  990. // Raise the event
  991. this.OnSelectedIndexChanged (new EventArgs ());
  992. this.Redraw (false);
  993. }
  994. }
  995. private void ListView_MouseMove (object sender, MouseEventArgs me)
  996. {
  997. // Column header is always at the top. It can
  998. // scroll only horizontally. So, we have to take
  999. // only horizontal scrolling into account
  1000. Point hit = new Point (me.X + h_marker, me.Y);
  1001. // non-null clicked_col means mouse down has happened
  1002. // on a column
  1003. if (this.clicked_column != null) {
  1004. if (this.clicked_column.pressed == false &&
  1005. this.clicked_column.Rect.Contains (hit)) {
  1006. this.clicked_column.pressed = true;
  1007. this.Redraw (false);
  1008. }
  1009. else if (this.clicked_column.pressed &&
  1010. ! this.clicked_column.Rect.Contains (hit)) {
  1011. this.clicked_column.pressed = false;
  1012. this.Redraw (false);
  1013. }
  1014. }
  1015. }
  1016. private void ListView_MouseUp (object sender, MouseEventArgs me)
  1017. {
  1018. this.Capture = false;
  1019. if (items.Count == 0)
  1020. return;
  1021. Point hit = new Point (me.X, me.Y);
  1022. if (this.clicked_column != null) {
  1023. if (this.clicked_column.pressed) {
  1024. this.clicked_column.pressed = false;
  1025. this.Redraw (false);
  1026. // Raise the ColumnClick event
  1027. this.OnColumnClick (new ColumnClickEventArgs
  1028. (this.clicked_column.Index));
  1029. }
  1030. }
  1031. // Raise the ItemActivate event
  1032. Rectangle rect = Rectangle.Empty;
  1033. if (this.clicked_item != null) {
  1034. if (this.view == View.Details && !this.full_row_select)
  1035. rect = this.clicked_item.LabelRect;
  1036. else
  1037. rect = this.clicked_item.EntireRect;
  1038. // We handle double click in a separate handler
  1039. if (this.activation != ItemActivation.Standard &&
  1040. rect.Contains (hit)) {
  1041. if (this.activation == ItemActivation.OneClick)
  1042. this.ItemActivate (this, EventArgs.Empty);
  1043. // ItemActivate is raised on the second click on the same item
  1044. else if (this.activation == ItemActivation.TwoClick) {
  1045. if (this.last_clicked_item == this.clicked_item) {
  1046. this.ItemActivate (this, EventArgs.Empty);
  1047. this.last_clicked_item = null;
  1048. }
  1049. else
  1050. this.last_clicked_item = this.clicked_item;
  1051. }
  1052. }
  1053. }
  1054. this.clicked_column = null;
  1055. this.clicked_item = null;
  1056. }
  1057. private void ListView_Paint (object sender, PaintEventArgs pe)
  1058. {
  1059. if (this.Width <= 0 || this.Height <= 0 ||
  1060. this.Visible == false || this.updating == true)
  1061. return;
  1062. CalculateScrollBars ();
  1063. ThemeEngine.Current.DrawListView (pe.Graphics,
  1064. pe.ClipRectangle, this);
  1065. // Raise the Paint event
  1066. if (Paint != null)
  1067. Paint (this, pe);
  1068. }
  1069. private void ListView_SizeChanged (object sender, EventArgs e)
  1070. {
  1071. CalculateListView (alignment);
  1072. }
  1073. public void SetFocusedItem (ListViewItem item)
  1074. {
  1075. if (focused_item != null)
  1076. focused_item.Focused = false;
  1077. if (item != null)
  1078. item.Focused = true;
  1079. focused_item = item;
  1080. }
  1081. private void HorizontalScroller (object sender, EventArgs e)
  1082. {
  1083. // Avoid unnecessary flickering, when button is
  1084. // kept pressed at the end
  1085. if (h_marker != h_scroll.Value) {
  1086. int pixels = h_marker - h_scroll.Value;
  1087. Rectangle area = client_area;
  1088. if (View == View.Details && Columns.Count > 0) {
  1089. area.Y += Columns[0].Ht;
  1090. area.Height -= Columns[0].Ht;
  1091. }
  1092. h_marker = h_scroll.Value;
  1093. XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
  1094. }
  1095. }
  1096. private void VerticalScroller (object sender, EventArgs e)
  1097. {
  1098. // Avoid unnecessary flickering, when button is
  1099. // kept pressed at the end
  1100. if (v_marker != v_scroll.Value) {
  1101. int pixels = v_marker - v_scroll.Value;
  1102. Rectangle area = client_area;
  1103. if (View == View.Details && Columns.Count > 0) {
  1104. area.Y += Columns[0].Ht;
  1105. area.Height -= Columns[0].Ht;
  1106. }
  1107. v_marker = v_scroll.Value;
  1108. XplatUI.ScrollWindow (Handle, area, 0, pixels, false);
  1109. }
  1110. }
  1111. #endregion // Internal Methods Properties
  1112. #region Protected Methods
  1113. protected override void CreateHandle ()
  1114. {
  1115. base.CreateHandle ();
  1116. }
  1117. protected override void Dispose (bool disposing)
  1118. {
  1119. if (disposing) {
  1120. h_scroll.Dispose ();
  1121. v_scroll.Dispose ();
  1122. if (large_image_list != null)
  1123. large_image_list.Dispose ();
  1124. if (small_image_list != null)
  1125. small_image_list.Dispose ();
  1126. if (state_image_list != null)
  1127. state_image_list.Dispose ();
  1128. }
  1129. base.Dispose (disposing);
  1130. }
  1131. protected override bool IsInputKey (Keys keyData)
  1132. {
  1133. switch (keyData) {
  1134. case Keys.Up:
  1135. case Keys.Down:
  1136. case Keys.PageUp:
  1137. case Keys.PageDown:
  1138. case Keys.Right:
  1139. case Keys.Left:
  1140. case Keys.End:
  1141. case Keys.Home:
  1142. return true;
  1143. default:
  1144. break;
  1145. }
  1146. return base.IsInputKey (keyData);
  1147. }
  1148. protected virtual void OnAfterLabelEdit (LabelEditEventArgs e)
  1149. {
  1150. if (AfterLabelEdit != null)
  1151. AfterLabelEdit (this, e);
  1152. }
  1153. protected virtual void OnBeforeLabelEdit (LabelEditEventArgs e)
  1154. {
  1155. if (BeforeLabelEdit != null)
  1156. BeforeLabelEdit (this, e);
  1157. }
  1158. protected virtual void OnColumnClick (ColumnClickEventArgs e)
  1159. {
  1160. if (ColumnClick != null)
  1161. ColumnClick (this, e);
  1162. }
  1163. protected override void OnEnabledChanged (EventArgs e)
  1164. {
  1165. base.OnEnabledChanged (e);
  1166. }
  1167. protected override void OnFontChanged (EventArgs e)
  1168. {
  1169. base.OnFontChanged (e);
  1170. Redraw (true);
  1171. }
  1172. protected override void OnHandleCreated (EventArgs e)
  1173. {
  1174. base.OnHandleCreated (e);
  1175. SuspendLayout ();
  1176. Controls.AddImplicit (this.v_scroll);
  1177. Controls.AddImplicit (this.h_scroll);
  1178. ResumeLayout ();
  1179. }
  1180. protected override void OnHandleDestroyed (EventArgs e)
  1181. {
  1182. base.OnHandleDestroyed (e);
  1183. }
  1184. protected virtual void OnItemActivate (EventArgs e)
  1185. {
  1186. if (ItemActivate != null)
  1187. ItemActivate (this, e);
  1188. }
  1189. protected virtual void OnItemCheck (ItemCheckEventArgs ice)
  1190. {
  1191. if (ItemCheck != null)
  1192. ItemCheck (this, ice);
  1193. }
  1194. protected virtual void OnItemDrag (ItemDragEventArgs e)
  1195. {
  1196. if (ItemDrag != null)
  1197. ItemDrag (this, e);
  1198. }
  1199. protected virtual void OnSelectedIndexChanged (EventArgs e)
  1200. {
  1201. if (SelectedIndexChanged != null)
  1202. SelectedIndexChanged (this, e);
  1203. }
  1204. protected override void OnSystemColorsChanged (EventArgs e)
  1205. {
  1206. base.OnSystemColorsChanged (e);
  1207. }
  1208. protected void RealizeProperties ()
  1209. {
  1210. // FIXME: TODO
  1211. }
  1212. protected void UpdateExtendedStyles ()
  1213. {
  1214. // FIXME: TODO
  1215. }
  1216. protected override void WndProc (ref Message m)
  1217. {
  1218. base.WndProc (ref m);
  1219. }
  1220. #endregion // Protected Methods
  1221. #region Public Instance Methods
  1222. public void ArrangeIcons ()
  1223. {
  1224. ArrangeIcons (this.alignment);
  1225. }
  1226. public void ArrangeIcons (ListViewAlignment alignment)
  1227. {
  1228. // Icons are arranged only if view is set to LargeIcon or SmallIcon
  1229. if (view == View.LargeIcon || view == View.SmallIcon) {
  1230. this.CalculateListView (alignment);
  1231. // we have done the calculations already
  1232. this.Redraw (false);
  1233. }
  1234. }
  1235. public void BeginUpdate ()
  1236. {
  1237. // flag to avoid painting
  1238. updating = true;
  1239. }
  1240. public void Clear ()
  1241. {
  1242. SetFocusedItem (null);
  1243. columns.Clear ();
  1244. items.Clear ();
  1245. this.Redraw (true);
  1246. }
  1247. public void EndUpdate ()
  1248. {
  1249. // flag to avoid painting
  1250. updating = false;
  1251. // probably, now we need a redraw with recalculations
  1252. this.Redraw (true);
  1253. }
  1254. public void EnsureVisible (int index)
  1255. {
  1256. if (index < 0 || index >= this.items.Count || this.scrollable == false)
  1257. return;
  1258. // dimensions of visible area
  1259. int view_wd = client_area.Width;
  1260. int view_ht = client_area.Height;
  1261. // visible area is decided by the h_marker and v_marker
  1262. Rectangle view_rect = new Rectangle (h_marker, v_marker, view_wd, view_ht);
  1263. // an item's bounding rect
  1264. Rectangle rect = this.items [index].EntireRect;
  1265. // we don't need to do anything if item is visible.
  1266. // visible area is represented by (0,0,view_wd,view_ht)
  1267. if (view_rect.Contains (rect))
  1268. return;
  1269. // Scroll Left or Up
  1270. if ((rect.Left < view_rect.Left) || (rect.Top < view_rect.Top)) {
  1271. if (rect.Left < view_rect.Left)
  1272. this.h_scroll.Value -= (view_rect.Left - rect.Left);
  1273. if (rect.Top < view_rect.Top)
  1274. this.v_scroll.Value -= (view_rect.Top - rect.Top);
  1275. }
  1276. // Scroll Right or Down
  1277. else {
  1278. if (rect.Right > view_rect.Right)
  1279. this.h_scroll.Value += (rect.Right - view_rect.Right);
  1280. if (rect.Bottom > view_rect.Bottom)
  1281. this.v_scroll.Value += (rect.Bottom - view_rect.Bottom);
  1282. }
  1283. }
  1284. public ListViewItem GetItemAt (int x, int y)
  1285. {
  1286. foreach (ListViewItem item in items) {
  1287. if (item.Bounds.Contains (x, y))
  1288. return item;
  1289. }
  1290. return null;
  1291. }
  1292. public Rectangle GetItemRect (int index)
  1293. {
  1294. return GetItemRect (index, ItemBoundsPortion.Entire);
  1295. }
  1296. public Rectangle GetItemRect (int index, ItemBoundsPortion portion)
  1297. {
  1298. if (index < 0 || index >= items.Count)
  1299. throw new IndexOutOfRangeException ("Invalid Index");
  1300. return items [index].GetBounds (portion);
  1301. }
  1302. public void Sort ()
  1303. {
  1304. if (sort_order != SortOrder.None)
  1305. items.list.Sort (item_sorter);
  1306. if (sort_order == SortOrder.Descending)
  1307. items.list.Reverse ();
  1308. this.Redraw (true);
  1309. }
  1310. public override string ToString ()
  1311. {
  1312. int count = this.Items.Count;
  1313. if (count == 0)
  1314. return string.Format ("System.Windows.Forms.ListView, Items.Count: 0");
  1315. else
  1316. return string.Format ("System.Windows.Forms.ListView, Items.Count: {0}, Items[0]: {1}", count, this.Items [0].ToString ());
  1317. }
  1318. #endregion // Public Instance Methods
  1319. #region Subclasses
  1320. public class CheckedIndexCollection : IList, ICollection, IEnumerable
  1321. {
  1322. internal ArrayList list;
  1323. private ListView owner;
  1324. #region Public Constructor
  1325. public CheckedIndexCollection (ListView owner)
  1326. {
  1327. list = new ArrayList ();
  1328. this.owner = owner;
  1329. }
  1330. #endregion // Public Constructor
  1331. #region Public Properties
  1332. [Browsable (false)]
  1333. public virtual int Count {
  1334. get { return list.Count; }
  1335. }
  1336. public virtual bool IsReadOnly {
  1337. get { return true; }
  1338. }
  1339. public int this [int index] {
  1340. get {
  1341. if (index < 0 || index >= list.Count)
  1342. throw new ArgumentOutOfRangeException ("Index out of range.");
  1343. return (int) list [index];
  1344. }
  1345. }
  1346. bool ICollection.IsSynchronized {
  1347. get { return list.IsSynchronized; }
  1348. }
  1349. object ICollection.SyncRoot {
  1350. get { return list.SyncRoot; }
  1351. }
  1352. bool IList.IsFixedSize {
  1353. get { return list.IsFixedSize; }
  1354. }
  1355. object IList.this [int index] {
  1356. get { return this [index]; }
  1357. set { throw new NotSupportedException ("SetItem operation is not supported."); }
  1358. }
  1359. #endregion // Public Properties
  1360. #region Public Methods
  1361. public bool Contains (int checkedIndex)
  1362. {
  1363. return list.Contains (checkedIndex);
  1364. }
  1365. public virtual IEnumerator GetEnumerator ()
  1366. {
  1367. return list.GetEnumerator ();
  1368. }
  1369. void ICollection.CopyTo (Array dest, int index)
  1370. {
  1371. list.CopyTo (dest, index);
  1372. }
  1373. int IList.Add (object value)
  1374. {
  1375. throw new NotSupportedException ("Add operation is not supported.");
  1376. }
  1377. void IList.Clear ()
  1378. {
  1379. throw new NotSupportedException ("Clear operation is not supported.");
  1380. }
  1381. bool IList.Contains (object checkedIndex)
  1382. {
  1383. return list.Contains (checkedIndex);
  1384. }
  1385. int IList.IndexOf (object checkedIndex)
  1386. {
  1387. return list.IndexOf (checkedIndex);
  1388. }
  1389. void IList.Insert (int index, object value)
  1390. {
  1391. throw new NotSupportedException ("Insert operation is not supported.");
  1392. }
  1393. void IList.Remove (object value)
  1394. {
  1395. throw new NotSupportedException ("Remove operation is not supported.");
  1396. }
  1397. void IList.RemoveAt (int index)
  1398. {
  1399. throw new NotSupportedException ("RemoveAt operation is not supported.");
  1400. }
  1401. public int IndexOf (int checkedIndex)
  1402. {
  1403. return list.IndexOf (checkedIndex);
  1404. }
  1405. #endregion // Public Methods
  1406. } // CheckedIndexCollection
  1407. public class CheckedListViewItemCollection : IList, ICollection, IEnumerable
  1408. {
  1409. internal ArrayList list;
  1410. private ListView owner;
  1411. #region Public Constructor
  1412. public CheckedListViewItemCollection (ListView owner)
  1413. {
  1414. list = new ArrayList ();
  1415. this.owner = owner;
  1416. }
  1417. #endregion // Public Constructor
  1418. #region Public Properties
  1419. [Browsable (false)]
  1420. public virtual int Count {
  1421. get { return list.Count; }
  1422. }
  1423. public virtual bool IsReadOnly {
  1424. get { return true; }
  1425. }
  1426. public ListViewItem this [int index] {
  1427. get {
  1428. if (index < 0 || index >= list.Count)
  1429. throw new ArgumentOutOfRangeException ("Index out of range.");
  1430. return (ListViewItem) list [index];
  1431. }
  1432. }
  1433. bool ICollection.IsSynchronized {
  1434. get { return list.IsSynchronized; }
  1435. }
  1436. object ICollection.SyncRoot {
  1437. get { return list.SyncRoot; }
  1438. }
  1439. bool IList.IsFixedSize {
  1440. get { return list.IsFixedSize; }
  1441. }
  1442. object IList.this [int index] {
  1443. get { return this [index]; }
  1444. set { throw new NotSupportedException ("SetItem operation is not supported."); }
  1445. }
  1446. #endregion // Public Properties
  1447. #region Public Methods
  1448. public bool Contains (ListViewItem item)
  1449. {
  1450. return list.Contains (item);
  1451. }
  1452. public virtual void CopyTo (Array dest, int index)
  1453. {
  1454. list.CopyTo (dest, index);
  1455. }
  1456. public virtual IEnumerator GetEnumerator ()
  1457. {
  1458. return list.GetEnumerator ();
  1459. }
  1460. int IList.Add (object value)
  1461. {
  1462. throw new NotSupportedException ("Add operation is not supported.");
  1463. }
  1464. void IList.Clear ()
  1465. {
  1466. throw new NotSupportedException ("Clear operation is not supported.");
  1467. }
  1468. bool IList.Contains (object item)
  1469. {
  1470. return list.Contains (item);
  1471. }
  1472. int IList.IndexOf (object item)
  1473. {
  1474. return list.IndexOf (item);
  1475. }
  1476. void IList.Insert (int index, object value)
  1477. {
  1478. throw new NotSupportedException ("Insert operation is not supported.");
  1479. }
  1480. void IList.Remove (object value)
  1481. {
  1482. throw new NotSupportedException ("Remove operation is not supported.");
  1483. }
  1484. void IList.RemoveAt (int index)
  1485. {
  1486. throw new NotSupportedException ("RemoveAt operation is not supported.");
  1487. }
  1488. public int IndexOf (ListViewItem item)
  1489. {
  1490. return list.IndexOf (item);
  1491. }
  1492. #endregion // Public Methods
  1493. } // CheckedListViewItemCollection
  1494. public class ColumnHeaderCollection : IList, ICollection, IEnumerable
  1495. {
  1496. internal ArrayList list;
  1497. private ListView owner;
  1498. #region Public Constructor
  1499. public ColumnHeaderCollection (ListView owner)
  1500. {
  1501. list = new ArrayList ();
  1502. this.owner = owner;
  1503. }
  1504. #endregion // Public Constructor
  1505. #region Public Properties
  1506. [Browsable (false)]
  1507. public virtual int Count {
  1508. get { return list.Count; }
  1509. }
  1510. public virtual bool IsReadOnly {
  1511. get { return false; }
  1512. }
  1513. public virtual ColumnHeader this [int index] {
  1514. get {
  1515. if (index < 0 || index >= list.Count)
  1516. throw new ArgumentOutOfRangeException ("Index out of range.");
  1517. return (ColumnHeader) list [index];
  1518. }
  1519. }
  1520. bool ICollection.IsSynchronized {
  1521. get { return list.IsSynchronized; }
  1522. }
  1523. object ICollection.SyncRoot {
  1524. get { return list.SyncRoot; }
  1525. }
  1526. bool IList.IsFixedSize {
  1527. get { return list.IsFixedSize; }
  1528. }
  1529. object IList.this [int index] {
  1530. get { return this [index]; }
  1531. set { throw new NotSupportedException ("SetItem operation is not supported."); }
  1532. }
  1533. #endregion // Public Properties
  1534. #region Public Methods
  1535. public virtual int Add (ColumnHeader value)
  1536. {
  1537. int idx;
  1538. value.owner = this.owner;
  1539. idx = list.Add (value);
  1540. owner.Redraw (true);
  1541. return idx;
  1542. }
  1543. public virtual ColumnHeader Add (string str, int width, HorizontalAlignment textAlign)
  1544. {
  1545. ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
  1546. this.Add (colHeader);
  1547. return colHeader;
  1548. }
  1549. public virtual void AddRange (ColumnHeader [] values)
  1550. {
  1551. foreach (ColumnHeader colHeader in values) {
  1552. colHeader.owner = this.owner;
  1553. Add (colHeader);
  1554. }
  1555. owner.Redraw (true);
  1556. }
  1557. public virtual void Clear ()
  1558. {
  1559. list.Clear ();
  1560. owner.Redraw (true);
  1561. }
  1562. public bool Contains (ColumnHeader value)
  1563. {
  1564. return list.Contains (value);
  1565. }
  1566. public virtual IEnumerator GetEnumerator ()
  1567. {
  1568. return list.GetEnumerator ();
  1569. }
  1570. void ICollection.CopyTo (Array dest, int index)
  1571. {
  1572. list.CopyTo (dest, index);
  1573. }
  1574. int IList.Add (object value)
  1575. {
  1576. if (! (value is ColumnHeader)) {
  1577. throw new ArgumentException ("Not of type ColumnHeader", "value");
  1578. }
  1579. return this.Add ((ColumnHeader) value);
  1580. }
  1581. bool IList.Contains (object value)
  1582. {
  1583. if (! (value is ColumnHeader)) {
  1584. throw new ArgumentException ("Not of type ColumnHeader", "value");
  1585. }
  1586. return this.Contains ((ColumnHeader) value);
  1587. }
  1588. int IList.IndexOf (object value)
  1589. {
  1590. if (! (value is ColumnHeader)) {
  1591. throw new ArgumentException ("Not of type ColumnHeader", "value");
  1592. }
  1593. return this.IndexOf ((ColumnHeader) value);
  1594. }
  1595. void IList.Insert (int index, object value)
  1596. {
  1597. if (! (value is ColumnHeader)) {
  1598. throw new ArgumentException ("Not of type ColumnHeader", "value");
  1599. }
  1600. this.Insert (index, (ColumnHeader) value);
  1601. }
  1602. void IList.Remove (object value)
  1603. {
  1604. if (! (value is ColumnHeader)) {
  1605. throw new ArgumentException ("Not of type ColumnHeader", "value");
  1606. }
  1607. this.Remove ((ColumnHeader) value);
  1608. }
  1609. public int IndexOf (ColumnHeader value)
  1610. {
  1611. return list.IndexOf (value);
  1612. }
  1613. public void Insert (int index, ColumnHeader value)
  1614. {
  1615. // LAMESPEC: MSDOCS say greater than or equal to the value of the Count property
  1616. // but it's really only greater.
  1617. if (index < 0 || index > list.Count)
  1618. throw new ArgumentOutOfRangeException ("Index out of range.");
  1619. value.owner = this.owner;
  1620. list.Insert (index, value);
  1621. owner.Redraw (true);
  1622. }
  1623. public void Insert (int index, string str, int width, HorizontalAlignment textAlign)
  1624. {
  1625. ColumnHeader colHeader = new ColumnHeader (this.owner, str, textAlign, width);
  1626. this.Insert (index, colHeader);
  1627. }
  1628. public virtual void Remove (ColumnHeader column)
  1629. {
  1630. // TODO: Update Column internal index ?
  1631. list.Remove (column);
  1632. owner.Redraw (true);
  1633. }
  1634. public virtual void RemoveAt (int index)
  1635. {
  1636. if (index < 0 || index >= list.Count)
  1637. throw new ArgumentOutOfRangeException ("Index out of range.");
  1638. // TODO: Update Column internal index ?
  1639. list.RemoveAt (index);
  1640. owner.Redraw (true);
  1641. }
  1642. #endregion // Public Methods
  1643. } // ColumnHeaderCollection
  1644. public class ListViewItemCollection : IList, ICollection, IEnumerable
  1645. {
  1646. internal ArrayList list;
  1647. private ListView owner;
  1648. #region Public Constructor
  1649. public ListViewItemCollection (ListView owner)
  1650. {
  1651. list = new ArrayList ();
  1652. this.owner = owner;
  1653. }
  1654. #endregion // Public Constructor
  1655. #region Public Properties
  1656. [Browsable (false)]
  1657. public virtual int Count {
  1658. get { return list.Count; }
  1659. }
  1660. public virtual bool IsReadOnly {
  1661. get { return false; }
  1662. }
  1663. public virtual ListViewItem this [int displayIndex] {
  1664. get {
  1665. if (displayIndex < 0 || displayIndex >= list.Count)
  1666. throw new ArgumentOutOfRangeException ("Index out of range.");
  1667. return (ListViewItem) list [displayIndex];
  1668. }
  1669. set {
  1670. if (displayIndex < 0 || displayIndex >= list.Count)
  1671. throw new ArgumentOutOfRangeException ("Index out of range.");
  1672. if (list.Contains (value))
  1673. throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
  1674. value.owner = this.owner;
  1675. list [displayIndex] = value;
  1676. owner.Redraw (true);
  1677. }
  1678. }
  1679. bool ICollection.IsSynchronized {
  1680. get { return list.IsSynchronized; }
  1681. }
  1682. object ICollection.SyncRoot {
  1683. get { return list.SyncRoot; }
  1684. }
  1685. bool IList.IsFixedSize {
  1686. get { return list.IsFixedSize; }
  1687. }
  1688. object IList.this [int index] {
  1689. get { return this [index]; }
  1690. set {
  1691. if (value is ListViewItem)
  1692. this [index] = (ListViewItem) value;
  1693. else
  1694. this [index] = new ListViewItem (value.ToString ());
  1695. }
  1696. }
  1697. #endregion // Public Properties
  1698. #region Public Methods
  1699. public virtual ListViewItem Add (ListViewItem value)
  1700. {
  1701. if (list.Contains (value))
  1702. throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "value");
  1703. value.owner = this.owner;
  1704. list.Add (value);
  1705. if (owner.Sorting != SortOrder.None)
  1706. owner.Sort ();
  1707. owner.Redraw (true);
  1708. return value;
  1709. }
  1710. public virtual ListViewItem Add (string text)
  1711. {
  1712. ListViewItem item = new ListViewItem (text);
  1713. return this.Add (item);
  1714. }
  1715. public virtual ListViewItem Add (string text, int imageIndex)
  1716. {
  1717. ListViewItem item = new ListViewItem (text, imageIndex);
  1718. return this.Add (item);
  1719. }
  1720. public void AddRange (ListViewItem [] values)
  1721. {
  1722. list.Clear ();
  1723. foreach (ListViewItem item in values) {
  1724. item.owner = this.owner;
  1725. list.Add (item);
  1726. }
  1727. if (owner.Sorting != SortOrder.None)
  1728. owner.Sort ();
  1729. owner.Redraw (true);
  1730. }
  1731. public virtual void Clear ()
  1732. {
  1733. list.Clear ();
  1734. }
  1735. public bool Contains (ListViewItem item)
  1736. {
  1737. return list.Contains (item);
  1738. }
  1739. public virtual void CopyTo (Array dest, int index)
  1740. {
  1741. list.CopyTo (dest, index);
  1742. }
  1743. public virtual IEnumerator GetEnumerator ()
  1744. {
  1745. return list.GetEnumerator ();
  1746. }
  1747. int IList.Add (object item)
  1748. {
  1749. int result;
  1750. ListViewItem li;
  1751. if (item is ListViewItem) {
  1752. li = (ListViewItem) item;
  1753. if (list.Contains (li))
  1754. throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
  1755. }
  1756. else
  1757. li = new ListViewItem (item.ToString ());
  1758. li.owner = this.owner;
  1759. result = list.Add (li);
  1760. owner.Redraw (true);
  1761. return result;
  1762. }
  1763. bool IList.Contains (object item)
  1764. {
  1765. return list.Contains (item);
  1766. }
  1767. int IList.IndexOf (object item)
  1768. {
  1769. return list.IndexOf (item);
  1770. }
  1771. void IList.Insert (int index, object item)
  1772. {
  1773. if (item is ListViewItem)
  1774. this.Insert (index, (ListViewItem) item);
  1775. else
  1776. this.Insert (index, item.ToString ());
  1777. }
  1778. void IList.Remove (object item)
  1779. {
  1780. if (list.Contains (item)) {
  1781. list.Remove (item);
  1782. owner.Redraw (true);
  1783. }
  1784. }
  1785. public int IndexOf (ListViewItem item)
  1786. {
  1787. return list.IndexOf (item);
  1788. }
  1789. public ListViewItem Insert (int index, ListViewItem item)
  1790. {
  1791. // LAMESPEC: MSDOCS say greater than or equal to the value of the Count property
  1792. // but it's really only greater.
  1793. if (index < 0 || index > list.Count)
  1794. throw new ArgumentOutOfRangeException ("Index out of range.");
  1795. if (list.Contains (item))
  1796. throw new ArgumentException ("An item cannot be added more than once. To add an item again, you need to clone it.", "item");
  1797. item.owner = this.owner;
  1798. list.Insert (index, item);
  1799. owner.Redraw (true);
  1800. return item;
  1801. }
  1802. public ListViewItem Insert (int index, string text)
  1803. {
  1804. return this.Insert (index, new ListViewItem (text));
  1805. }
  1806. public ListViewItem Insert (int index, string text, int imageIndex)
  1807. {
  1808. return this.Insert (index, new ListViewItem (text, imageIndex));
  1809. }
  1810. public virtual void Remove (ListViewItem item)
  1811. {
  1812. if (list.Contains (item)) {
  1813. list.Remove (item);
  1814. owner.Redraw (true);
  1815. }
  1816. }
  1817. public virtual void RemoveAt (int index)
  1818. {
  1819. if (index < 0 || index >= list.Count)
  1820. throw new ArgumentOutOfRangeException ("Index out of range.");
  1821. list.RemoveAt (index);
  1822. owner.Redraw (false);
  1823. }
  1824. #endregion // Public Methods
  1825. } // ListViewItemCollection
  1826. public class SelectedIndexCollection : IList, ICollection, IEnumerable
  1827. {
  1828. internal ArrayList list;
  1829. private ListView owner;
  1830. #region Public Constructor
  1831. public SelectedIndexCollection (ListView owner)
  1832. {
  1833. list = new ArrayList ();
  1834. this.owner = owner;
  1835. }
  1836. #endregion // Public Constructor
  1837. #region Public Properties
  1838. [Browsable (false)]
  1839. public virtual int Count {
  1840. get { return list.Count; }
  1841. }
  1842. public virtual bool IsReadOnly {
  1843. get { return true; }
  1844. }
  1845. public int this [int index] {
  1846. get {
  1847. if (index < 0 || index >= list.Count)
  1848. throw new ArgumentOutOfRangeException ("Index out of range.");
  1849. return (int) list [index];
  1850. }
  1851. }
  1852. bool ICollection.IsSynchronized {
  1853. get { return list.IsSynchronized; }
  1854. }
  1855. object ICollection.SyncRoot {
  1856. get { return list.SyncRoot; }
  1857. }
  1858. bool IList.IsFixedSize {
  1859. get { return list.IsFixedSize; }
  1860. }
  1861. object IList.this [int index] {
  1862. get { return this [index]; }
  1863. set { throw new NotSupportedException ("SetItem operation is not supported."); }
  1864. }
  1865. #endregion // Public Properties
  1866. #region Public Methods
  1867. public bool Contains (int selectedIndex)
  1868. {
  1869. return list.Contains (selectedIndex);
  1870. }
  1871. public virtual void CopyTo (Array dest, int index)
  1872. {
  1873. list.CopyTo (dest, index);
  1874. }
  1875. public virtual IEnumerator GetEnumerator ()
  1876. {
  1877. return list.GetEnumerator ();
  1878. }
  1879. int IList.Add (object value)
  1880. {
  1881. throw new NotSupportedException ("Add operation is not supported.");
  1882. }
  1883. void IList.Clear ()
  1884. {
  1885. throw new NotSupportedException ("Clear operation is not supported.");
  1886. }
  1887. bool IList.Contains (object selectedIndex)
  1888. {
  1889. return list.Contains (selectedIndex);
  1890. }
  1891. int IList.IndexOf (object selectedIndex)
  1892. {
  1893. return list.IndexOf (selectedIndex);
  1894. }
  1895. void IList.Insert (int index, object value)
  1896. {
  1897. throw new NotSupportedException ("Insert operation is not supported.");
  1898. }
  1899. void IList.Remove (object value)
  1900. {
  1901. throw new NotSupportedException ("Remove operation is not supported.");
  1902. }
  1903. void IList.RemoveAt (int index)
  1904. {
  1905. throw new NotSupportedException ("RemoveAt operation is not supported.");
  1906. }
  1907. public int IndexOf (int selectedIndex)
  1908. {
  1909. return list.IndexOf (selectedIndex);
  1910. }
  1911. #endregion // Public Methods
  1912. } // SelectedIndexCollection
  1913. public class SelectedListViewItemCollection : IList, ICollection, IEnumerable
  1914. {
  1915. internal ArrayList list;
  1916. private ListView owner;
  1917. #region Public Constructor
  1918. public SelectedListViewItemCollection (ListView owner)
  1919. {
  1920. list = new ArrayList ();
  1921. this.owner = owner;
  1922. }
  1923. #endregion // Public Constructor
  1924. #region Public Properties
  1925. [Browsable (false)]
  1926. public virtual int Count {
  1927. get { return list.Count; }
  1928. }
  1929. public virtual bool IsReadOnly {
  1930. get { return true; }
  1931. }
  1932. public ListViewItem this [int index] {
  1933. get {
  1934. if (index < 0 || index >= list.Count)
  1935. throw new ArgumentOutOfRangeException ("Index out of range.");
  1936. return (ListViewItem) list [index];
  1937. }
  1938. }
  1939. bool ICollection.IsSynchronized {
  1940. get { return list.IsSynchronized; }
  1941. }
  1942. object ICollection.SyncRoot {
  1943. get { return list.SyncRoot; }
  1944. }
  1945. bool IList.IsFixedSize {
  1946. get { return list.IsFixedSize; }
  1947. }
  1948. object IList.this [int index] {
  1949. get { return this [index]; }
  1950. set { throw new NotSupportedException ("SetItem operation is not supported."); }
  1951. }
  1952. #endregion // Public Properties
  1953. #region Public Methods
  1954. public virtual void Clear ()
  1955. {
  1956. // mark the items as unselected before clearing the list
  1957. for (int i = 0; i < list.Count; i++)
  1958. ((ListViewItem) list [i]).selected = false;
  1959. list.Clear ();
  1960. if (owner != null)
  1961. owner.Invalidate ();
  1962. }
  1963. public bool Contains (ListViewItem item)
  1964. {
  1965. return list.Contains (item);
  1966. }
  1967. public virtual void CopyTo (Array dest, int index)
  1968. {
  1969. list.CopyTo (dest, index);
  1970. }
  1971. public virtual IEnumerator GetEnumerator ()
  1972. {
  1973. return list.GetEnumerator ();
  1974. }
  1975. int IList.Add (object value)
  1976. {
  1977. throw new NotSupportedException ("Add operation is not supported.");
  1978. }
  1979. bool IList.Contains (object item)
  1980. {
  1981. return list.Contains (item);
  1982. }
  1983. int IList.IndexOf (object item)
  1984. {
  1985. return list.IndexOf (item);
  1986. }
  1987. void IList.Insert (int index, object value)
  1988. {
  1989. throw new NotSupportedException ("Insert operation is not supported.");
  1990. }
  1991. void IList.Remove (object value)
  1992. {
  1993. throw new NotSupportedException ("Remove operation is not supported.");
  1994. }
  1995. void IList.RemoveAt (int index)
  1996. {
  1997. throw new NotSupportedException ("RemoveAt operation is not supported.");
  1998. }
  1999. public int IndexOf (ListViewItem item)
  2000. {
  2001. return list.IndexOf (item);
  2002. }
  2003. #endregion // Public Methods
  2004. } // SelectedListViewItemCollection
  2005. #endregion // Subclasses
  2006. }
  2007. }