| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061 |
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (c) 2004-2006 Novell, Inc.
- //
- // Authors:
- // Jordi Mas i Hernandez, [email protected]
- // Mike Kestner <[email protected]>
- //
- // COMPLETE
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.ComponentModel.Design.Serialization;
- using System.Globalization;
- using System.Reflection;
- using System.Runtime.InteropServices;
- #if NET_2_0
- using System.Collections.Generic;
- #endif
- namespace System.Windows.Forms
- {
- [DefaultProperty("Items")]
- [DefaultEvent("SelectedIndexChanged")]
- [Designer ("System.Windows.Forms.Design.ListBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
- #if NET_2_0
- [DefaultBindingProperty ("SelectedValue")]
- [ClassInterface (ClassInterfaceType.AutoDispatch)]
- [ComVisible (true)]
- #endif
- public class ListBox : ListControl
- {
- public const int DefaultItemHeight = 13;
- public const int NoMatches = -1;
-
- internal enum ItemNavigation
- {
- First,
- Last,
- Next,
- Previous,
- NextPage,
- PreviousPage,
- PreviousColumn,
- NextColumn
- }
-
- Hashtable item_heights;
- private int item_height = -1;
- private int column_width = 0;
- private int requested_height;
- private DrawMode draw_mode = DrawMode.Normal;
- private int horizontal_extent = 0;
- private bool horizontal_scrollbar = false;
- private bool integral_height = true;
- private bool multicolumn = false;
- private bool scroll_always_visible = false;
- private SelectedIndexCollection selected_indices;
- private SelectedObjectCollection selected_items;
- private SelectionMode selection_mode = SelectionMode.One;
- private bool sorted = false;
- private bool use_tabstops = true;
- private int column_width_internal = 120;
- private ImplicitVScrollBar vscrollbar;
- private ImplicitHScrollBar hscrollbar;
- private int hbar_offset;
- private bool suspend_layout;
- private bool ctrl_pressed = false;
- private bool shift_pressed = false;
- private bool explicit_item_height = false;
- private int top_index = 0;
- private int last_visible_index = 0;
- private Rectangle items_area;
- private int focused_item = -1;
- private ObjectCollection items;
- #if NET_2_0
- private IntegerCollection custom_tab_offsets;
- private Padding padding;
- private bool use_custom_tab_offsets;
- #endif
- public ListBox ()
- {
- items = CreateItemCollection ();
- selected_indices = new SelectedIndexCollection (this);
- selected_items = new SelectedObjectCollection (this);
- requested_height = bounds.Height;
- InternalBorderStyle = BorderStyle.Fixed3D;
- BackColor = ThemeEngine.Current.ColorWindow;
- /* Vertical scrollbar */
- vscrollbar = new ImplicitVScrollBar ();
- vscrollbar.Minimum = 0;
- vscrollbar.SmallChange = 1;
- vscrollbar.LargeChange = 1;
- vscrollbar.Maximum = 0;
- vscrollbar.ValueChanged += new EventHandler (VerticalScrollEvent);
- vscrollbar.Visible = false;
- /* Horizontal scrollbar */
- hscrollbar = new ImplicitHScrollBar ();
- hscrollbar.Minimum = 0;
- hscrollbar.SmallChange = 1;
- hscrollbar.LargeChange = 1;
- hscrollbar.Maximum = 0;
- hscrollbar.Visible = false;
- hscrollbar.ValueChanged += new EventHandler (HorizontalScrollEvent);
- Controls.AddImplicit (vscrollbar);
- Controls.AddImplicit (hscrollbar);
- /* Events */
- MouseDown += new MouseEventHandler (OnMouseDownLB);
- MouseMove += new MouseEventHandler (OnMouseMoveLB);
- MouseUp += new MouseEventHandler (OnMouseUpLB);
- MouseWheel += new MouseEventHandler (OnMouseWheelLB);
- KeyDown += new KeyEventHandler (OnKeyDownLB);
- KeyUp += new KeyEventHandler (OnKeyUpLB);
- GotFocus += new EventHandler (OnGotFocus);
- LostFocus += new EventHandler (OnLostFocus);
-
- SetStyle (ControlStyles.UserPaint, false);
- #if NET_2_0
- custom_tab_offsets = new IntegerCollection (this);
- #endif
- }
- #region Events
- static object DrawItemEvent = new object ();
- static object MeasureItemEvent = new object ();
- static object SelectedIndexChangedEvent = new object ();
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackgroundImageChanged {
- add { base.BackgroundImageChanged += value; }
- remove { base.BackgroundImageChanged -= value; }
- }
- #if NET_2_0
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackgroundImageLayoutChanged {
- add { base.BackgroundImageLayoutChanged += value; }
- remove { base.BackgroundImageLayoutChanged -= value; }
- }
- [Browsable (true)]
- [EditorBrowsable (EditorBrowsableState.Always)]
- #else
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Advanced)]
- #endif
- public new event EventHandler Click {
- add { base.Click += value; }
- remove { base.Click -= value; }
- }
- public event DrawItemEventHandler DrawItem {
- add { Events.AddHandler (DrawItemEvent, value); }
- remove { Events.RemoveHandler (DrawItemEvent, value); }
- }
- public event MeasureItemEventHandler MeasureItem {
- add { Events.AddHandler (MeasureItemEvent, value); }
- remove { Events.RemoveHandler (MeasureItemEvent, value); }
- }
- #if NET_2_0
- [Browsable (true)]
- [EditorBrowsable (EditorBrowsableState.Always)]
- public new event MouseEventHandler MouseClick {
- add { base.MouseClick += value; }
- remove { base.MouseClick -= value; }
- }
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler PaddingChanged {
- add { base.PaddingChanged += value; }
- remove { base.PaddingChanged -= value; }
- }
- #endif
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public new event PaintEventHandler Paint {
- add { base.Paint += value; }
- remove { base.Paint -= value; }
- }
- public event EventHandler SelectedIndexChanged {
- add { Events.AddHandler (SelectedIndexChangedEvent, value); }
- remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
- }
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Advanced)]
- public new event EventHandler TextChanged {
- add { base.TextChanged += value; }
- remove { base.TextChanged -= value; }
- }
- #endregion // Events
- #region Public Properties
- public override Color BackColor {
- get { return base.BackColor; }
- set {
- if (base.BackColor == value)
- return;
- base.BackColor = value;
- base.Refresh (); // Careful. Calling the base method is not the same that calling
- } // the overriden one that refresh also all the items
- }
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public override Image BackgroundImage {
- get { return base.BackgroundImage; }
- set {
- base.BackgroundImage = value;
- base.Refresh ();
- }
- }
- #if NET_2_0
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- public override ImageLayout BackgroundImageLayout {
- get { return base.BackgroundImageLayout; }
- set { base.BackgroundImageLayout = value; }
- }
- #endif
- [DefaultValue (BorderStyle.Fixed3D)]
- [DispId(-504)]
- public BorderStyle BorderStyle {
- get { return InternalBorderStyle; }
- set {
- InternalBorderStyle = value;
- UpdateListBoxBounds ();
- }
- }
- [DefaultValue (0)]
- [Localizable (true)]
- public int ColumnWidth {
- get { return column_width; }
- set {
- if (value < 0)
- throw new ArgumentException ("A value less than zero is assigned to the property.");
- column_width = value;
- if (value == 0)
- ColumnWidthInternal = 120;
- else
- ColumnWidthInternal = value;
- base.Refresh ();
- }
- }
- protected override CreateParams CreateParams {
- get { return base.CreateParams;}
- }
- #if NET_2_0
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
- public IntegerCollection CustomTabOffsets {
- get { return custom_tab_offsets; }
- }
- #endif
- protected override Size DefaultSize {
- get { return new Size (120, 96); }
- }
- [RefreshProperties(RefreshProperties.Repaint)]
- [DefaultValue (DrawMode.Normal)]
- public virtual DrawMode DrawMode {
- get { return draw_mode; }
- set {
- if (!Enum.IsDefined (typeof (DrawMode), value))
- throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for DrawMode", value));
-
- if (value == DrawMode.OwnerDrawVariable && multicolumn == true)
- throw new ArgumentException ("Cannot have variable height and multicolumn");
- if (draw_mode == value)
- return;
- draw_mode = value;
- if (draw_mode == DrawMode.OwnerDrawVariable)
- item_heights = new Hashtable ();
- else
- item_heights = null;
- if (Parent != null)
- Parent.PerformLayout (this, "DrawMode");
- base.Refresh ();
- }
- }
- #if NET_2_0
- public override Font Font {
- get { return base.Font; }
- set { base.Font = value; }
- }
- #endif
- public override Color ForeColor {
- get { return base.ForeColor; }
- set {
- if (base.ForeColor == value)
- return;
- base.ForeColor = value;
- base.Refresh ();
- }
- }
- [DefaultValue (0)]
- [Localizable (true)]
- public int HorizontalExtent {
- get { return horizontal_extent; }
- set {
- if (horizontal_extent == value)
- return;
- horizontal_extent = value;
- base.Refresh ();
- }
- }
- [DefaultValue (false)]
- [Localizable (true)]
- public bool HorizontalScrollbar {
- get { return horizontal_scrollbar; }
- set {
- if (horizontal_scrollbar == value)
- return;
- horizontal_scrollbar = value;
- UpdateScrollBars ();
- base.Refresh ();
- }
- }
- [DefaultValue (true)]
- [Localizable (true)]
- [RefreshProperties(RefreshProperties.Repaint)]
- public bool IntegralHeight {
- get { return integral_height; }
- set {
- if (integral_height == value)
- return;
- integral_height = value;
- UpdateListBoxBounds ();
- }
- }
- [DefaultValue (13)]
- [Localizable (true)]
- [RefreshProperties(RefreshProperties.Repaint)]
- public virtual int ItemHeight {
- get {
- if (item_height == -1) {
- SizeF sz = TextRenderer.MeasureString ("The quick brown Fox", Font);
- item_height = (int) sz.Height;
- }
- return item_height;
- }
- set {
- if (value > 255)
- throw new ArgumentOutOfRangeException ("The ItemHeight property was set beyond 255 pixels");
- explicit_item_height = true;
- if (item_height == value)
- return;
- item_height = value;
- if (IntegralHeight)
- UpdateListBoxBounds ();
- LayoutListBox ();
- }
- }
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
- [Localizable (true)]
- [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
- #if NET_2_0
- [MergableProperty (false)]
- #endif
- public ObjectCollection Items {
- get { return items; }
- }
- [DefaultValue (false)]
- public bool MultiColumn {
- get { return multicolumn; }
- set {
- if (multicolumn == value)
- return;
- if (value == true && DrawMode == DrawMode.OwnerDrawVariable)
- throw new ArgumentException ("A multicolumn ListBox cannot have a variable-sized height.");
-
- multicolumn = value;
- LayoutListBox ();
- Invalidate ();
- }
- }
- #if NET_2_0
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public new Padding Padding {
- get { return padding; }
- set { padding = value; }
- }
- #endif
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [EditorBrowsable (EditorBrowsableState.Advanced)]
- public int PreferredHeight {
- get {
- int itemsHeight = 0;
- if (draw_mode == DrawMode.Normal)
- itemsHeight = FontHeight * items.Count;
- else if (draw_mode == DrawMode.OwnerDrawFixed)
- itemsHeight = ItemHeight * items.Count;
- else if (draw_mode == DrawMode.OwnerDrawVariable) {
- for (int i = 0; i < items.Count; i++)
- itemsHeight += (int) item_heights [Items [i]];
- }
-
- return itemsHeight;
- }
- }
- public override RightToLeft RightToLeft {
- get { return base.RightToLeft; }
- set {
- base.RightToLeft = value;
- if (base.RightToLeft == RightToLeft.Yes)
- StringFormat.Alignment = StringAlignment.Far;
- else
- StringFormat.Alignment = StringAlignment.Near;
- base.Refresh ();
- }
- }
- // Only affects the Vertical ScrollBar
- [DefaultValue (false)]
- [Localizable (true)]
- public bool ScrollAlwaysVisible {
- get { return scroll_always_visible; }
- set {
- if (scroll_always_visible == value)
- return;
- scroll_always_visible = value;
- UpdateScrollBars ();
- }
- }
- [Bindable(true)]
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public override int SelectedIndex {
- get {
- if (selected_indices == null)
- return -1;
-
- return selected_indices.Count > 0 ? selected_indices [0] : -1;
- }
- set {
- if (value < -1 || value >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- if (SelectionMode == SelectionMode.None)
- throw new ArgumentException ("cannot call this method if SelectionMode is SelectionMode.None");
- if (value == -1)
- selected_indices.Clear ();
- else
- selected_indices.Add (value);
- }
- }
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public SelectedIndexCollection SelectedIndices {
- get { return selected_indices; }
- }
- [Bindable(true)]
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public object SelectedItem {
- get {
- if (SelectedItems.Count > 0)
- return SelectedItems[0];
- else
- return null;
- }
- set {
- if (value != null && !Items.Contains (value))
- return; // FIXME: this is probably an exception
-
- SelectedIndex = value == null ? - 1 : Items.IndexOf (value);
- }
- }
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public SelectedObjectCollection SelectedItems {
- get {return selected_items;}
- }
- [DefaultValue (SelectionMode.One)]
- public virtual SelectionMode SelectionMode {
- get { return selection_mode; }
- set {
- if (!Enum.IsDefined (typeof (SelectionMode), value))
- throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for SelectionMode", value));
- if (selection_mode == value)
- return;
-
- selection_mode = value;
-
- switch (selection_mode) {
- case SelectionMode.None:
- SelectedIndices.Clear ();
- break;
- case SelectionMode.One:
- // FIXME: Probably this can be improved
- ArrayList old_selection = (ArrayList) SelectedIndices.List.Clone ();
- for (int i = 1; i < old_selection.Count; i++)
- SelectedIndices.Remove ((int)old_selection [i]);
- break;
- default:
- break;
- }
- }
- }
- [DefaultValue (false)]
- public bool Sorted {
- get { return sorted; }
- set {
- if (sorted == value)
- return;
- sorted = value;
- if (sorted)
- Sort ();
- }
- }
- [Bindable (false)]
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [EditorBrowsable (EditorBrowsableState.Advanced)]
- public override string Text {
- get {
- if (SelectionMode != SelectionMode.None && SelectedIndex != -1)
- return GetItemText (SelectedItem);
- return base.Text;
- }
- set {
- base.Text = value;
- if (SelectionMode == SelectionMode.None)
- return;
- int index;
- index = FindStringExact (value);
- if (index == -1)
- return;
- SelectedIndex = index;
- }
- }
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public int TopIndex {
- get { return top_index; }
- set {
- if (value == top_index)
- return;
- if (value < 0 || value >= Items.Count)
- return;
- int page_size = (items_area.Height / ItemHeight);
-
- if (Items.Count < page_size)
- value = 0;
- else if (!multicolumn)
- top_index = Math.Min (value, Items.Count - page_size);
- else
- top_index = value;
-
- UpdateTopItem ();
- base.Refresh ();
- }
- }
- #if NET_2_0
- [Browsable (false)]
- [DefaultValue (false)]
- public bool UseCustomTabOffsets {
- get { return use_custom_tab_offsets; }
- set {
- if (use_custom_tab_offsets != value) {
- use_custom_tab_offsets = value;
- CalculateTabStops ();
- }
- }
- }
- #endif
- [DefaultValue (true)]
- public bool UseTabStops {
- get { return use_tabstops; }
- set {
- if (use_tabstops == value)
- return;
- use_tabstops = value;
- CalculateTabStops ();
- }
- }
- #if NET_2_0
- protected override bool AllowSelection {
- get {
- return SelectionMode != SelectionMode.None;
- }
- }
- #endif
- #endregion Public Properties
- #region Private Properties
- private int ColumnWidthInternal {
- get { return column_width_internal; }
- set { column_width_internal = value; }
- }
- private int row_count = 1;
- private int RowCount {
- get {
- return MultiColumn ? row_count : Items.Count;
- }
- }
- #endregion Private Properties
- #region UIA Framework Properties
- internal ScrollBar UIAHScrollBar {
- get { return hscrollbar; }
- }
- internal ScrollBar UIAVScrollBar {
- get { return vscrollbar; }
- }
- #endregion UIA Framework Properties
- #region Public Methods
- #if NET_2_0
- [Obsolete ("this method has been deprecated")]
- #endif
- protected virtual void AddItemsCore (object[] value)
- {
- Items.AddRange (value);
- }
- public void BeginUpdate ()
- {
- suspend_layout = true;
- }
- public void ClearSelected ()
- {
- selected_indices.Clear ();
- }
- protected virtual ObjectCollection CreateItemCollection ()
- {
- return new ObjectCollection (this);
- }
- public void EndUpdate ()
- {
- suspend_layout = false;
- LayoutListBox ();
- base.Refresh ();
- }
- public int FindString (String s)
- {
- return FindString (s, -1);
- }
- public int FindString (string s, int startIndex)
- {
- if (Items.Count == 0)
- return -1; // No exception throwing if empty
- if (startIndex < -1 || startIndex >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- startIndex = (startIndex == Items.Count - 1) ? 0 : startIndex + 1;
- int i = startIndex;
- while (true) {
- string text = GetItemText (Items [i]);
- if (CultureInfo.CurrentCulture.CompareInfo.IsPrefix (text, s,
- CompareOptions.IgnoreCase))
- return i;
- i = (i == Items.Count - 1) ? 0 : i + 1;
- if (i == startIndex)
- break;
- }
- return NoMatches;
- }
- public int FindStringExact (string s)
- {
- return FindStringExact (s, -1);
- }
- public int FindStringExact (string s, int startIndex)
- {
- if (Items.Count == 0)
- return -1; // No exception throwing if empty
- if (startIndex < -1 || startIndex >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- startIndex = (startIndex + 1 == Items.Count) ? 0 : startIndex + 1;
- int i = startIndex;
- while (true) {
- if (String.Compare (GetItemText (Items[i]), s, true) == 0)
- return i;
- i = (i + 1 == Items.Count) ? 0 : i + 1;
- if (i == startIndex)
- break;
- }
- return NoMatches;
- }
- public int GetItemHeight (int index)
- {
- if (index < 0 || index >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
-
- if (DrawMode == DrawMode.OwnerDrawVariable && IsHandleCreated == true) {
-
- object o = Items [index];
- if (item_heights.Contains (o))
- return (int) item_heights [o];
-
- MeasureItemEventArgs args = new MeasureItemEventArgs (DeviceContext, index, ItemHeight);
- OnMeasureItem (args);
- item_heights [o] = args.ItemHeight;
- return args.ItemHeight;
- }
- return ItemHeight;
- }
- public Rectangle GetItemRectangle (int index)
- {
- if (index < 0 || index >= Items.Count)
- throw new ArgumentOutOfRangeException ("GetItemRectangle index out of range.");
- Rectangle rect = new Rectangle ();
- if (MultiColumn) {
- int col = index / RowCount;
- rect.Y = ((index - top_index) % RowCount) * ItemHeight;
- rect.X = col * ColumnWidthInternal;
- rect.Height = ItemHeight;
- rect.Width = ColumnWidthInternal;
- } else {
- rect.X = 0;
- rect.Height = GetItemHeight (index);
- rect.Width = items_area.Width;
-
- if (DrawMode == DrawMode.OwnerDrawVariable) {
- rect.Y = 0;
- if (index >= top_index) {
- for (int i = top_index; i < index; i++) {
- rect.Y += GetItemHeight (i);
- }
- } else {
- for (int i = index; i < top_index; i++) {
- rect.Y -= GetItemHeight (i);
- }
- }
- } else {
- rect.Y = ItemHeight * (index - top_index);
- }
- }
- if (this is CheckedListBox)
- rect.Width += 15;
-
- return rect;
- }
- #if NET_2_0
- [EditorBrowsable (EditorBrowsableState.Advanced)]
- protected override Rectangle GetScaledBounds (Rectangle bounds, SizeF factor, BoundsSpecified specified)
- {
- bounds.Height = requested_height;
- return base.GetScaledBounds (bounds, factor, specified);
- }
- #endif
- public bool GetSelected (int index)
- {
- if (index < 0 || index >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- return SelectedIndices.Contains (index);
- }
- public int IndexFromPoint (Point p)
- {
- return IndexFromPoint (p.X, p.Y);
- }
- // Only returns visible points
- public int IndexFromPoint (int x, int y)
- {
- if (Items.Count == 0) {
- return -1;
- }
- for (int i = top_index; i <= last_visible_index; i++) {
- if (GetItemRectangle (i).Contains (x,y) == true)
- return i;
- }
- return -1;
- }
- protected override void OnChangeUICues (UICuesEventArgs e)
- {
- base.OnChangeUICues (e);
- }
- protected override void OnDataSourceChanged (EventArgs e)
- {
- base.OnDataSourceChanged (e);
- BindDataItems ();
-
- if (DataSource == null || DataManager == null) {
- SelectedIndex = -1;
- } else {
- SelectedIndex = DataManager.Position;
- }
- }
- protected override void OnDisplayMemberChanged (EventArgs e)
- {
- base.OnDisplayMemberChanged (e);
- if (DataManager == null || !IsHandleCreated)
- return;
- BindDataItems ();
- base.Refresh ();
- }
- protected virtual void OnDrawItem (DrawItemEventArgs e)
- {
- switch (DrawMode) {
- case DrawMode.OwnerDrawFixed:
- case DrawMode.OwnerDrawVariable:
- DrawItemEventHandler eh = (DrawItemEventHandler)(Events [DrawItemEvent]);
- if (eh != null)
- eh (this, e);
- break;
- default:
- ThemeEngine.Current.DrawListBoxItem (this, e);
- break;
- }
- }
- protected override void OnFontChanged (EventArgs e)
- {
- base.OnFontChanged (e);
- if (use_tabstops)
- StringFormat.SetTabStops (0, new float [] {(float)(Font.Height * 3.7)});
- if (explicit_item_height) {
- base.Refresh ();
- } else {
- SizeF sz = TextRenderer.MeasureString ("The quick brown Fox", Font);
- item_height = (int) sz.Height;
- if (IntegralHeight)
- UpdateListBoxBounds ();
- LayoutListBox ();
- }
- }
- protected override void OnHandleCreated (EventArgs e)
- {
- base.OnHandleCreated (e);
- if (IntegralHeight)
- UpdateListBoxBounds ();
- LayoutListBox ();
- EnsureVisible (focused_item);
- }
- protected override void OnHandleDestroyed (EventArgs e)
- {
- base.OnHandleDestroyed (e);
- }
- protected virtual void OnMeasureItem (MeasureItemEventArgs e)
- {
- if (draw_mode != DrawMode.OwnerDrawVariable)
- return;
- MeasureItemEventHandler eh = (MeasureItemEventHandler)(Events [MeasureItemEvent]);
- if (eh != null)
- eh (this, e);
- }
- protected override void OnParentChanged (EventArgs e)
- {
- base.OnParentChanged (e);
- }
- protected override void OnResize (EventArgs e)
- {
- base.OnResize (e);
- if (canvas_size.IsEmpty || MultiColumn)
- LayoutListBox ();
-
- Invalidate ();
- }
- protected override void OnSelectedIndexChanged (EventArgs e)
- {
- base.OnSelectedIndexChanged (e);
- EventHandler eh = (EventHandler)(Events [SelectedIndexChangedEvent]);
- if (eh != null)
- eh (this, e);
- }
- protected override void OnSelectedValueChanged (EventArgs e)
- {
- base.OnSelectedValueChanged (e);
- }
- public override void Refresh ()
- {
- if (draw_mode == DrawMode.OwnerDrawVariable)
- item_heights.Clear ();
-
- base.Refresh ();
- }
- protected override void RefreshItem (int index)
- {
- if (index < 0 || index >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
-
- if (draw_mode == DrawMode.OwnerDrawVariable)
- item_heights.Remove (Items [index]);
- }
- #if NET_2_0
- protected override void RefreshItems ()
- {
- for (int i = 0; i < Items.Count; i++) {
- RefreshItem (i);
- }
- }
- public override void ResetBackColor ()
- {
- base.ResetBackColor ();
- }
- public override void ResetForeColor ()
- {
- base.ResetForeColor ();
- }
- protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
- {
- base.ScaleControl (factor, specified);
- }
- #endif
- private int SnapHeightToIntegral (int height)
- {
- int border;
- switch (border_style) {
- case BorderStyle.Fixed3D:
- border = ThemeEngine.Current.Border3DSize.Height;
- break;
- case BorderStyle.FixedSingle:
- border = ThemeEngine.Current.BorderSize.Height;
- break;
- case BorderStyle.None:
- default:
- border = 0;
- break;
- }
- height -= (2 * border);
- height -= height % ItemHeight;
- height += (2 * border);
- return height;
- }
-
- protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
- {
- if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height)
- requested_height = height;
- if (IntegralHeight && IsHandleCreated)
- height = SnapHeightToIntegral (height);
- base.SetBoundsCore (x, y, width, height, specified);
- UpdateScrollBars ();
- last_visible_index = LastVisibleItem ();
- }
- protected override void SetItemCore (int index, object value)
- {
- if (index < 0 || index >= Items.Count)
- return;
- Items[index] = value;
- }
- protected override void SetItemsCore (IList value)
- {
- BeginUpdate ();
- try {
- Items.Clear ();
- Items.AddItems (value);
- } finally {
- EndUpdate ();
- }
- }
- public void SetSelected (int index, bool value)
- {
- if (index < 0 || index >= Items.Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- if (SelectionMode == SelectionMode.None)
- throw new InvalidOperationException ();
- if (value)
- SelectedIndices.Add (index);
- else
- SelectedIndices.Remove (index);
- }
- protected virtual void Sort ()
- {
- Sort (true);
- }
- //
- // Sometimes we could need to Sort, and request a Refresh
- // in a different place, to not have the painting done twice
- //
- void Sort (bool paint)
- {
- if (Items.Count == 0)
- return;
- Items.Sort ();
- if (paint)
- base.Refresh ();
- }
- public override string ToString ()
- {
- return base.ToString ();
- }
- protected virtual void WmReflectCommand (ref Message m)
- {
- }
- protected override void WndProc (ref Message m)
- {
- base.WndProc (ref m);
- }
- #endregion Public Methods
- #region Private Methods
- private void CalculateTabStops ()
- {
- if (use_tabstops) {
- #if NET_2_0
- if (use_custom_tab_offsets) {
- float[] f = new float[custom_tab_offsets.Count];
- custom_tab_offsets.CopyTo (f, 0);
- StringFormat.SetTabStops (0, f);
- }
- else
- #endif
- StringFormat.SetTabStops (0, new float[] { (float)(Font.Height * 3.7) });
- } else
- StringFormat.SetTabStops (0, new float[0]);
- this.Invalidate ();
- }
- private Size canvas_size;
- private void LayoutListBox ()
- {
- if (!IsHandleCreated || suspend_layout)
- return;
- if (MultiColumn)
- LayoutMultiColumn ();
- else
- LayoutSingleColumn ();
- last_visible_index = LastVisibleItem ();
- UpdateScrollBars ();
- }
- private void LayoutSingleColumn ()
- {
- int height, width;
- switch (DrawMode) {
- case DrawMode.OwnerDrawVariable:
- height = 0;
- width = HorizontalExtent;
- for (int i = 0; i < Items.Count; i++) {
- height += GetItemHeight (i);
- }
- break;
- case DrawMode.OwnerDrawFixed:
- height = Items.Count * ItemHeight;
- width = HorizontalExtent;
- break;
- case DrawMode.Normal:
- default:
- height = Items.Count * ItemHeight;
- width = 0;
- for (int i = 0; i < Items.Count; i++) {
- SizeF sz = TextRenderer.MeasureString (GetItemText (Items[i]), Font);
- int t = (int)sz.Width;
-
- if (this is CheckedListBox)
- t += 15;
-
- if (t > width)
- width = t;
- }
- break;
- }
- canvas_size = new Size (width, height);
- }
- private void LayoutMultiColumn ()
- {
- int usable_height = ClientRectangle.Height - (ScrollAlwaysVisible ? hscrollbar.Height : 0);
- row_count = Math.Max (1, usable_height / ItemHeight);
- int cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
- Size sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
- if (!ScrollAlwaysVisible && sz.Width > ClientRectangle.Width && row_count > 1) {
- usable_height = ClientRectangle.Height - hscrollbar.Height;
- row_count = Math.Max (1, usable_height / ItemHeight);
- cols = (int) Math.Ceiling ((float)Items.Count / (float) row_count);
- sz = new Size (cols * ColumnWidthInternal, row_count * ItemHeight);
- }
- canvas_size = sz;
- }
- internal void Draw (Rectangle clip, Graphics dc)
- {
- Theme theme = ThemeEngine.Current;
- if (hscrollbar.Visible && vscrollbar.Visible) {
- // Paint the dead space in the bottom right corner
- Rectangle rect = new Rectangle (hscrollbar.Right, vscrollbar.Bottom, vscrollbar.Width, hscrollbar.Height);
- if (rect.IntersectsWith (clip))
- dc.FillRectangle (theme.ResPool.GetSolidBrush (theme.ColorControl), rect);
- }
- dc.FillRectangle (theme.ResPool.GetSolidBrush (BackColor), items_area);
- if (Items.Count == 0)
- return;
- for (int i = top_index; i <= last_visible_index; i++) {
- Rectangle rect = GetItemDisplayRectangle (i, top_index);
- if (!clip.IntersectsWith (rect))
- continue;
- DrawItemState state = DrawItemState.None;
- if (SelectedIndices.Contains (i))
- state |= DrawItemState.Selected;
-
- if (has_focus && FocusedItem == i)
- state |= DrawItemState.Focus;
-
- if (MultiColumn == false && hscrollbar != null && hscrollbar.Visible) {
- rect.X -= hscrollbar.Value;
- rect.Width += hscrollbar.Value;
- }
- OnDrawItem (new DrawItemEventArgs (dc, Font, rect, i, state, ForeColor, BackColor));
- }
- }
- // Converts a GetItemRectangle to a one that we can display
- internal Rectangle GetItemDisplayRectangle (int index, int first_displayble)
- {
- Rectangle item_rect;
- Rectangle first_item_rect = GetItemRectangle (first_displayble);
- item_rect = GetItemRectangle (index);
- item_rect.X -= first_item_rect.X;
- item_rect.Y -= first_item_rect.Y;
-
- // Subtract the checkboxes from the width
- if (this is CheckedListBox)
- item_rect.Width -= 14;
- return item_rect;
- }
- // Value Changed
- private void HorizontalScrollEvent (object sender, EventArgs e)
- {
- if (multicolumn) {
- int top_item = top_index;
- int last_item = last_visible_index;
- top_index = RowCount * hscrollbar.Value;
- last_visible_index = LastVisibleItem ();
- if (top_item != top_index || last_item != last_visible_index)
- Invalidate (items_area);
- }
- else {
- int old_offset = hbar_offset;
- hbar_offset = hscrollbar.Value;
- if (hbar_offset < 0)
- hbar_offset = 0;
- if (IsHandleCreated)
- XplatUI.ScrollWindow (Handle, items_area, old_offset - hbar_offset, 0, false);
- }
- }
- // Only returns visible points. The diference of with IndexFromPoint is that the rectangle
- // has screen coordinates
- private int IndexAtClientPoint (int x, int y)
- {
- if (Items.Count == 0)
- return -1;
-
- if (x < 0)
- x = 0;
- else if (x > ClientRectangle.Right)
- x = ClientRectangle.Right;
- if (y < 0)
- y = 0;
- else if (y > ClientRectangle.Bottom)
- y = ClientRectangle.Bottom;
- for (int i = top_index; i <= last_visible_index; i++)
- if (GetItemDisplayRectangle (i, top_index).Contains (x, y))
- return i;
- return -1;
- }
- internal override bool IsInputCharInternal (char charCode)
- {
- return true;
- }
- private int LastVisibleItem ()
- {
- Rectangle item_rect;
- int top_y = items_area.Y + items_area.Height;
- int i = 0;
- if (top_index >= Items.Count)
- return top_index;
- for (i = top_index; i < Items.Count; i++) {
- item_rect = GetItemDisplayRectangle (i, top_index);
- if (MultiColumn) {
- if (item_rect.X > items_area.Width)
- return i - 1;
- } else {
- if (item_rect.Y + item_rect.Height > top_y)
- return i;
- }
- }
- return i - 1;
- }
- private void UpdateTopItem ()
- {
- if (MultiColumn) {
- int col = top_index / RowCount;
-
- if (col > hscrollbar.Maximum)
- hscrollbar.Value = hscrollbar.Maximum;
- else
- hscrollbar.Value = col;
- } else {
- if (top_index > vscrollbar.Maximum)
- vscrollbar.Value = vscrollbar.Maximum;
- else
- vscrollbar.Value = top_index;
- Scroll (vscrollbar, vscrollbar.Value - top_index);
- }
- }
-
- // Navigates to the indicated item and returns the new item
- private int NavigateItemVisually (ItemNavigation navigation)
- {
- int page_size, columns, selected_index = -1;
- if (multicolumn) {
- columns = items_area.Width / ColumnWidthInternal;
- page_size = columns * RowCount;
- if (page_size == 0) {
- page_size = RowCount;
- }
- } else {
- page_size = items_area.Height / ItemHeight;
- }
- switch (navigation) {
- case ItemNavigation.PreviousColumn: {
- if (SelectedIndex - RowCount < 0) {
- return -1;
- }
- if (SelectedIndex - RowCount < top_index) {
- top_index = SelectedIndex - RowCount;
- UpdateTopItem ();
- }
-
- selected_index = SelectedIndex - RowCount;
- break;
- }
-
- case ItemNavigation.NextColumn: {
- if (SelectedIndex + RowCount >= Items.Count) {
- break;
- }
- if (SelectedIndex + RowCount > last_visible_index) {
- top_index = SelectedIndex;
- UpdateTopItem ();
- }
-
- selected_index = SelectedIndex + RowCount;
- break;
- }
- case ItemNavigation.First: {
- top_index = 0;
- selected_index = 0;
- UpdateTopItem ();
- break;
- }
- case ItemNavigation.Last: {
- int rows = items_area.Height / ItemHeight;
-
- if (multicolumn) {
- selected_index = Items.Count - 1;
- break;
- }
- if (Items.Count < rows) {
- top_index = 0;
- selected_index = Items.Count - 1;
- UpdateTopItem ();
- } else {
- top_index = Items.Count - rows;
- selected_index = Items.Count - 1;
- UpdateTopItem ();
- }
- break;
- }
- case ItemNavigation.Next: {
- if (FocusedItem == Items.Count - 1)
- return -1;
- if (multicolumn) {
- selected_index = FocusedItem + 1;
- break;
- }
-
- int bottom = 0;
- ArrayList heights = new ArrayList ();
- if (draw_mode == DrawMode.OwnerDrawVariable) {
- for (int i = top_index; i <= FocusedItem + 1; i++) {
- int h = GetItemHeight (i);
- bottom += h;
- heights.Add (h);
- }
- } else {
- bottom = ((FocusedItem + 1) - top_index + 1) * ItemHeight;
- }
- if (bottom >= items_area.Height) {
- int overhang = bottom - items_area.Height;
- int offset = 0;
- if (draw_mode == DrawMode.OwnerDrawVariable)
- while (overhang > 0)
- overhang -= (int) heights [offset];
- else
- offset = (int) Math.Ceiling ((float)overhang / (float) ItemHeight);
- top_index += offset;
- UpdateTopItem ();
- }
- selected_index = FocusedItem + 1;
- break;
- }
- case ItemNavigation.Previous: {
- if (FocusedItem > 0) {
- if (FocusedItem - 1 < top_index) {
- top_index--;
- UpdateTopItem ();
- }
- selected_index = FocusedItem - 1;
- }
- break;
- }
- case ItemNavigation.NextPage: {
- if (Items.Count < page_size) {
- NavigateItemVisually (ItemNavigation.Last);
- break;
- }
- if (FocusedItem + page_size - 1 >= Items.Count) {
- top_index = Items.Count - page_size;
- UpdateTopItem ();
- selected_index = Items.Count - 1;
- }
- else {
- if (FocusedItem + page_size - 1 > last_visible_index) {
- top_index = FocusedItem;
- UpdateTopItem ();
- }
-
- selected_index = FocusedItem + page_size - 1;
- }
-
- break;
- }
- case ItemNavigation.PreviousPage: {
-
- int rows = items_area.Height / ItemHeight;
- if (FocusedItem - (rows - 1) <= 0) {
- top_index = 0;
- UpdateTopItem ();
- selected_index = 0;
- }
- else {
- if (SelectedIndex - (rows - 1) < top_index) {
- top_index = FocusedItem - (rows - 1);
- UpdateTopItem ();
- }
-
- selected_index = FocusedItem - (rows - 1);
- }
-
- break;
- }
- default:
- break;
- }
-
- return selected_index;
- }
-
-
- private void OnGotFocus (object sender, EventArgs e)
- {
- if (Items.Count == 0)
- return;
- if (FocusedItem == -1)
- FocusedItem = 0;
- InvalidateItem (FocusedItem);
- }
-
- private void OnLostFocus (object sender, EventArgs e)
- {
- if (FocusedItem != -1)
- InvalidateItem (FocusedItem);
- }
- private bool KeySearch (Keys key)
- {
- char c = (char) key;
- if (!Char.IsLetterOrDigit (c))
- return false;
- int idx = FindString (c.ToString (), SelectedIndex);
- if (idx != ListBox.NoMatches)
- SelectedIndex = idx;
- return true;
- }
- internal void OnKeyDownLB (object sender, KeyEventArgs e)
- {
- int new_item = -1;
-
- if (Items.Count == 0)
- return;
- if (KeySearch (e.KeyCode))
- return;
- switch (e.KeyCode) {
-
- case Keys.ControlKey:
- ctrl_pressed = true;
- break;
-
- case Keys.ShiftKey:
- shift_pressed = true;
- break;
-
- case Keys.Home:
- new_item = NavigateItemVisually (ItemNavigation.First);
- break;
- case Keys.End:
- new_item = NavigateItemVisually (ItemNavigation.Last);
- break;
- case Keys.Up:
- new_item = NavigateItemVisually (ItemNavigation.Previous);
- break;
-
- case Keys.Down:
- new_item = NavigateItemVisually (ItemNavigation.Next);
- break;
-
- case Keys.PageUp:
- new_item = NavigateItemVisually (ItemNavigation.PreviousPage);
- break;
-
- case Keys.PageDown:
- new_item = NavigateItemVisually (ItemNavigation.NextPage);
- break;
- case Keys.Right:
- if (multicolumn == true) {
- new_item = NavigateItemVisually (ItemNavigation.NextColumn);
- }
- break;
-
- case Keys.Left:
- if (multicolumn == true) {
- new_item = NavigateItemVisually (ItemNavigation.PreviousColumn);
- }
- break;
-
- case Keys.Space:
- if (selection_mode == SelectionMode.MultiSimple) {
- SelectedItemFromNavigation (FocusedItem);
- }
- break;
-
- default:
- break;
- }
-
- if (new_item != -1) {
- FocusedItem = new_item;
- if (selection_mode != SelectionMode.MultiSimple)
- SelectedItemFromNavigation (new_item);
- }
- }
-
- private void OnKeyUpLB (object sender, KeyEventArgs e)
- {
- switch (e.KeyCode) {
- case Keys.ControlKey:
- ctrl_pressed = false;
- break;
- case Keys.ShiftKey:
- shift_pressed = false;
- break;
- default:
- break;
- }
- }
- internal void InvalidateItem (int index)
- {
- if (!IsHandleCreated)
- return;
- Rectangle bounds = GetItemDisplayRectangle (index, top_index);
- if (ClientRectangle.IntersectsWith (bounds))
- Invalidate (bounds);
- }
- internal virtual void OnItemClick (int index)
- {
- OnSelectedIndexChanged (EventArgs.Empty);
- OnSelectedValueChanged (EventArgs.Empty);
- }
- int anchor = -1;
- int[] prev_selection;
- bool button_pressed = false;
- Point button_pressed_loc = new Point (-1, -1);
- private void SelectExtended (int index)
- {
- SuspendLayout ();
- ArrayList new_selection = new ArrayList ();
- int start = anchor < index ? anchor : index;
- int end = anchor > index ? anchor : index;
- for (int i = start; i <= end; i++)
- new_selection.Add (i);
- if (ctrl_pressed)
- foreach (int i in prev_selection)
- if (!new_selection.Contains (i))
- new_selection.Add (i);
- // Need to make a copy since we can't enumerate and modify the collection
- // at the same time
- ArrayList sel_indices = (ArrayList) selected_indices.List.Clone ();
- foreach (int i in sel_indices)
- if (!new_selection.Contains (i))
- selected_indices.Remove (i);
- foreach (int i in new_selection)
- if (!sel_indices.Contains (i))
- selected_indices.AddCore (i);
- ResumeLayout ();
- }
- private void OnMouseDownLB (object sender, MouseEventArgs e)
- {
- // Only do stuff with the left mouse button
- if ((e.Button & MouseButtons.Left) == 0)
- return;
-
- int index = IndexAtClientPoint (e.X, e.Y);
- if (index == -1)
- return;
- switch (SelectionMode) {
- case SelectionMode.One:
- SelectedIndices.AddCore (index); // Unselects previous one
- break;
- case SelectionMode.MultiSimple:
- if (SelectedIndices.Contains (index))
- SelectedIndices.RemoveCore (index);
- else
- SelectedIndices.AddCore (index);
- break;
- case SelectionMode.MultiExtended:
- shift_pressed = (XplatUI.State.ModifierKeys & Keys.Shift) != 0;
- ctrl_pressed = (XplatUI.State.ModifierKeys & Keys.Control) != 0;
- if (shift_pressed) {
- SelectedIndices.ClearCore ();
- SelectExtended (index);
- break;
- }
- anchor = index;
- if (ctrl_pressed) {
- prev_selection = new int [SelectedIndices.Count];
- SelectedIndices.CopyTo (prev_selection, 0);
- if (SelectedIndices.Contains (index))
- SelectedIndices.RemoveCore (index);
- else
- SelectedIndices.AddCore (index);
- break;
- }
- SelectedIndices.ClearCore ();
- SelectedIndices.AddCore (index);
- break;
- case SelectionMode.None:
- break;
- default:
- return;
- }
- button_pressed = true;
- button_pressed_loc = new Point (e.X, e.Y);
- FocusedItem = index;
- }
- private void OnMouseMoveLB (object sender, MouseEventArgs e)
- {
- // Don't take into account MouseMove events generated with MouseDown
- if (!button_pressed || button_pressed_loc == new Point (e.X, e.Y))
- return;
- int index = IndexAtClientPoint (e.X, e.Y);
- if (index == -1)
- return;
- switch (SelectionMode) {
- case SelectionMode.One:
- SelectedIndices.AddCore (index); // Unselects previous one
- break;
- case SelectionMode.MultiSimple:
- break;
- case SelectionMode.MultiExtended:
- SelectExtended (index);
- break;
- case SelectionMode.None:
- break;
- default:
- return;
- }
- FocusedItem = index;
- }
- internal override void OnDragDropEnd (DragDropEffects effects)
- {
- // In the case of a DnD operation (started on MouseDown)
- // there will be no MouseUp event, so we need to reset
- // the state here
- button_pressed = false;
- }
- private void OnMouseUpLB (object sender, MouseEventArgs e)
- {
- // Only do stuff with the left mouse button
- if ((e.Button & MouseButtons.Left) == 0)
- return;
- if (e.Clicks > 1) {
- OnDoubleClick (EventArgs.Empty);
- #if NET_2_0
- OnMouseDoubleClick (e);
- #endif
- }
- else if (e.Clicks == 1) {
- OnClick (EventArgs.Empty);
- #if NET_2_0
- OnMouseClick (e);
- #endif
- }
-
- if (!button_pressed)
- return;
- int index = IndexAtClientPoint (e.X, e.Y);
- OnItemClick (index);
- button_pressed = ctrl_pressed = shift_pressed = false;
- }
- private void Scroll (ScrollBar scrollbar, int delta)
- {
- if (delta == 0 || !scrollbar.Visible || !scrollbar.Enabled)
- return;
- int max;
- if (scrollbar == hscrollbar)
- max = hscrollbar.Maximum - (items_area.Width / ColumnWidthInternal) + 1;
- else
- max = vscrollbar.Maximum - (items_area.Height / ItemHeight) + 1;
- int val = scrollbar.Value + delta;
- if (val > max)
- val = max;
- else if (val < scrollbar.Minimum)
- val = scrollbar.Minimum;
- scrollbar.Value = val;
- }
- private void OnMouseWheelLB (object sender, MouseEventArgs me)
- {
- if (Items.Count == 0)
- return;
- int lines = me.Delta / 120;
- if (MultiColumn)
- Scroll (hscrollbar, -SystemInformation.MouseWheelScrollLines * lines);
- else
- Scroll (vscrollbar, -lines);
- }
- internal override void OnPaintInternal (PaintEventArgs pevent)
- {
- if (suspend_layout)
- return;
- Draw (pevent.ClipRectangle, pevent.Graphics);
- }
- internal void RepositionScrollBars ()
- {
- if (vscrollbar.is_visible) {
- vscrollbar.Size = new Size (vscrollbar.Width, items_area.Height);
- vscrollbar.Location = new Point (items_area.Width, 0);
- }
- if (hscrollbar.is_visible) {
- hscrollbar.Size = new Size (items_area.Width, hscrollbar.Height);
- hscrollbar.Location = new Point (0, items_area.Height);
- }
- }
- // An item navigation operation (mouse or keyboard) has caused to select a new item
- internal void SelectedItemFromNavigation (int index)
- {
- switch (SelectionMode) {
- case SelectionMode.None:
- // .Net doesn't select the item, only ensures that it's visible
- // and fires the selection related events
- EnsureVisible (index);
- OnSelectedIndexChanged (EventArgs.Empty);
- OnSelectedValueChanged (EventArgs.Empty);
- break;
- case SelectionMode.One: {
- SelectedIndex = index;
- break;
- }
- case SelectionMode.MultiSimple: {
- if (SelectedIndex == -1) {
- SelectedIndex = index;
- } else {
- if (SelectedIndices.Contains (index))
- SelectedIndices.Remove (index);
- else {
- SelectedIndices.AddCore (index);
- OnSelectedIndexChanged (EventArgs.Empty);
- OnSelectedValueChanged (EventArgs.Empty);
- }
- }
- break;
- }
-
- case SelectionMode.MultiExtended: {
- if (SelectedIndex == -1) {
- SelectedIndex = index;
- } else {
- if (ctrl_pressed == false && shift_pressed == false) {
- SelectedIndices.Clear ();
- }
-
- if (shift_pressed == true) {
- ShiftSelection (index);
- } else { // ctrl_pressed or single item
- SelectedIndices.AddCore (index);
- }
- OnSelectedIndexChanged (EventArgs.Empty);
- OnSelectedValueChanged (EventArgs.Empty);
- }
- break;
- }
-
- default:
- break;
- }
- }
-
- private void ShiftSelection (int index)
- {
- int shorter_item = -1, dist = Items.Count + 1, cur_dist;
-
- foreach (int idx in selected_indices) {
- if (idx > index) {
- cur_dist = idx - index;
- } else {
- cur_dist = index - idx;
- }
- if (cur_dist < dist) {
- dist = cur_dist;
- shorter_item = idx;
- }
- }
-
- if (shorter_item != -1) {
- int start, end;
-
- if (shorter_item > index) {
- start = index;
- end = shorter_item;
- } else {
- start = shorter_item;
- end = index;
- }
-
- selected_indices.Clear ();
- for (int idx = start; idx <= end; idx++) {
- selected_indices.AddCore (idx);
- }
- }
- }
-
- internal int FocusedItem {
- get { return focused_item; }
- set {
- if (focused_item == value)
- return;
- int prev = focused_item;
-
- focused_item = value;
-
- if (has_focus == false)
- return;
- if (prev != -1)
- InvalidateItem (prev);
-
- if (value != -1)
- InvalidateItem (value);
- }
- }
- StringFormat string_format;
- internal StringFormat StringFormat {
- get {
- if (string_format == null) {
- string_format = new StringFormat ();
- if (RightToLeft == RightToLeft.Yes)
- string_format.Alignment = StringAlignment.Far;
- else
- string_format.Alignment = StringAlignment.Near;
- CalculateTabStops ();
- }
- return string_format;
- }
- }
- internal virtual void CollectionChanged ()
- {
- if (sorted)
- Sort (false);
- if (Items.Count == 0) {
- selected_indices.List.Clear ();
- focused_item = -1;
- top_index = 0;
- }
- if (Items.Count <= focused_item)
- focused_item = Items.Count - 1;
- if (!IsHandleCreated || suspend_layout)
- return;
- LayoutListBox ();
- base.Refresh ();
- }
- void EnsureVisible (int index)
- {
- if (!IsHandleCreated || index == -1)
- return;
- if (index < top_index) {
- top_index = index;
- UpdateTopItem ();
- Invalidate ();
- } else if (!multicolumn) {
- int rows = items_area.Height / ItemHeight;
- if (index >= (top_index + rows))
- top_index = index - rows + 1;
- UpdateTopItem ();
- } else {
- int rows = Math.Max (1, items_area.Height / ItemHeight);
- int cols = Math.Max (1, items_area.Width / ColumnWidthInternal);
-
- if (index >= (top_index + (rows * cols))) {
- int incolumn = index / rows;
- top_index = (incolumn - (cols - 1)) * rows;
- UpdateTopItem ();
- Invalidate ();
- }
- }
- }
- private void UpdateListBoxBounds ()
- {
- if (IsHandleCreated)
- SetBoundsInternal (bounds.X, bounds.Y, bounds.Width, IntegralHeight ? SnapHeightToIntegral (requested_height) : requested_height, BoundsSpecified.None);
- }
- private void UpdateScrollBars ()
- {
- items_area = ClientRectangle;
- if (UpdateHorizontalScrollBar ()) {
- items_area.Height -= hscrollbar.Height;
- if (UpdateVerticalScrollBar ()) {
- items_area.Width -= vscrollbar.Width;
- UpdateHorizontalScrollBar ();
- }
- } else if (UpdateVerticalScrollBar ()) {
- items_area.Width -= vscrollbar.Width;
- if (UpdateHorizontalScrollBar ()) {
- items_area.Height -= hscrollbar.Height;
- UpdateVerticalScrollBar ();
- }
- }
- RepositionScrollBars ();
- }
- /* Determines if the horizontal scrollbar has to be displyed */
- private bool UpdateHorizontalScrollBar ()
- {
- bool show = false;
- bool enabled = true;
- if (MultiColumn) {
- if (canvas_size.Width > items_area.Width) {
- show = true;
- hscrollbar.Maximum = canvas_size.Width / ColumnWidthInternal - 1;
- } else if (ScrollAlwaysVisible == true) {
- enabled = false;
- show = true;
- hscrollbar.Maximum = 0;
- }
- } else if (canvas_size.Width > ClientRectangle.Width && HorizontalScrollbar) {
- show = true;
- hscrollbar.Maximum = canvas_size.Width;
- hscrollbar.LargeChange = Math.Max (0, items_area.Width);
- } else if (horizontal_scrollbar) {
- show = true;
- enabled = false;
- hscrollbar.Maximum = 0;
- }
- hbar_offset = hscrollbar.Value;
- hscrollbar.Enabled = enabled;
- hscrollbar.Visible = show;
- return show;
- }
- /* Determines if the vertical scrollbar has to be displyed */
- private bool UpdateVerticalScrollBar ()
- {
- if (MultiColumn || (Items.Count == 0 && !scroll_always_visible)) {
- vscrollbar.Visible = false;
- return false;
- } else if (Items.Count == 0) {
- vscrollbar.Visible = true;
- vscrollbar.Enabled = false;
- vscrollbar.Maximum = 0;
- return true;
- }
- bool show = false;
- bool enabled = true;
- if (canvas_size.Height > items_area.Height) {
- show = true;
- vscrollbar.Maximum = Items.Count - 1;
- vscrollbar.LargeChange = Math.Max (items_area.Height / ItemHeight, 0);
- } else if (ScrollAlwaysVisible) {
- show = true;
- enabled = false;
- vscrollbar.Maximum = 0;
- }
- vscrollbar.Enabled = enabled;
- vscrollbar.Visible = show;
- return show;
- }
- // Value Changed
- private void VerticalScrollEvent (object sender, EventArgs e)
- {
- int top_item = top_index;
- top_index = /*row_count + */ vscrollbar.Value;
- last_visible_index = LastVisibleItem ();
- int delta = (top_item - top_index) * ItemHeight;
- if (DrawMode == DrawMode.OwnerDrawVariable) {
- delta = 0;
- if (top_index < top_item)
- for (int i = top_index; i < top_item; i++)
- delta += GetItemHeight (i);
- else
- for (int i = top_item; i < top_index; i++)
- delta -= GetItemHeight (i);
- }
- if (IsHandleCreated)
- XplatUI.ScrollWindow (Handle, items_area, 0, delta, false);
- }
- #endregion Private Methods
- #if NET_2_0
- public class IntegerCollection : IList, ICollection, IEnumerable
- {
- private ListBox owner;
- private List<int> list;
-
- #region Public Constructor
- public IntegerCollection (ListBox owner)
- {
- this.owner = owner;
- list = new List<int> ();
- }
- #endregion
- #region Public Properties
- [Browsable (false)]
- public int Count {
- get { return list.Count; }
- }
-
- public int this [int index] {
- get { return list[index]; }
- set { list[index] = value; owner.CalculateTabStops (); }
- }
- #endregion
- #region Public Methods
- public int Add (int item)
- {
- // This collection does not allow duplicates
- if (!list.Contains (item)) {
- list.Add (item);
- list.Sort ();
- owner.CalculateTabStops ();
- }
-
- return list.IndexOf (item);
- }
-
- public void AddRange (int[] items)
- {
- AddItems (items);
- }
-
- public void AddRange (IntegerCollection value)
- {
- AddItems (value);
- }
- void AddItems (IList items)
- {
- if (items == null)
- throw new ArgumentNullException ("items");
- foreach (int i in items)
- if (!list.Contains (i))
- list.Add (i);
- list.Sort ();
- }
- public void Clear ()
- {
- list.Clear ();
- owner.CalculateTabStops ();
- }
-
- public bool Contains (int item)
- {
- return list.Contains (item);
- }
-
- public void CopyTo (Array destination, int index)
- {
- for (int i = 0; i < list.Count; i++)
- destination.SetValue (list[i], index++);
- }
-
- public int IndexOf (int item)
- {
- return list.IndexOf (item);
- }
-
- public void Remove (int item)
- {
- list.Remove (item);
- list.Sort ();
- owner.CalculateTabStops ();
- }
-
- public void RemoveAt (int index)
- {
- if (index < 0)
- throw new IndexOutOfRangeException ();
- list.RemoveAt (index);
- list.Sort ();
- owner.CalculateTabStops ();
- }
- #endregion
- #region IEnumerable Members
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return list.GetEnumerator ();
- }
- #endregion
- #region IList Members
- int IList.Add (object item)
- {
- int? intValue = item as int?;
- if (!intValue.HasValue)
- throw new ArgumentException ("item");
- return Add (intValue.Value);
- }
- void IList.Clear ()
- {
- Clear ();
- }
- bool IList.Contains (object item)
- {
- int? intValue = item as int?;
- if (!intValue.HasValue)
- return false;
- return Contains (intValue.Value);
- }
- int IList.IndexOf (object item)
- {
- int? intValue = item as int?;
- if (!intValue.HasValue)
- return -1;
- return IndexOf (intValue.Value);
- }
- void IList.Insert (int index, object value)
- {
- throw new NotSupportedException (string.Format (
- CultureInfo.InvariantCulture, "No items "
- + "can be inserted into {0}, since it is"
- + " a sorted collection.", this.GetType ()));
- }
- bool IList.IsFixedSize
- {
- get { return false; }
- }
- bool IList.IsReadOnly
- {
- get { return false; }
- }
- void IList.Remove (object value)
- {
- int? intValue = value as int?;
- if (!intValue.HasValue)
- throw new ArgumentException ("value");
- Remove (intValue.Value);
- }
- void IList.RemoveAt (int index)
- {
- RemoveAt (index);
- }
- object IList.this[int index] {
- get { return this[index]; }
- set { this[index] = (int)value; }
- }
- #endregion
- #region ICollection Members
- bool ICollection.IsSynchronized {
- get { return true; }
- }
- object ICollection.SyncRoot {
- get { return this; }
- }
- #endregion
- }
- #endif
- [ListBindable (false)]
- public class ObjectCollection : IList, ICollection, IEnumerable
- {
- internal class ListObjectComparer : IComparer
- {
- public int Compare (object a, object b)
- {
- string str1 = a.ToString ();
- string str2 = b.ToString ();
- return str1.CompareTo (str2);
- }
- }
- private ListBox owner;
- internal ArrayList object_items = new ArrayList ();
-
- #region UIA Framework Events
- #if NET_2_0
- //NOTE:
- // We are using Reflection to add/remove internal events.
- // Class ListProvider uses the events.
- //
- //Event used to generate UIA StructureChangedEvent
- static object UIACollectionChangedEvent = new object ();
- internal event CollectionChangeEventHandler UIACollectionChanged {
- add { owner.Events.AddHandler (UIACollectionChangedEvent, value); }
- remove { owner.Events.RemoveHandler (UIACollectionChangedEvent, value); }
- }
- internal void OnUIACollectionChangedEvent (CollectionChangeEventArgs args)
- {
- CollectionChangeEventHandler eh
- = (CollectionChangeEventHandler) owner.Events [UIACollectionChangedEvent];
- if (eh != null)
- eh (owner, args);
- }
- #endif
- #endregion UIA Framework Events
- public ObjectCollection (ListBox owner)
- {
- this.owner = owner;
- }
- public ObjectCollection (ListBox owner, object[] value)
- {
- this.owner = owner;
- AddRange (value);
- }
- public ObjectCollection (ListBox owner, ObjectCollection value)
- {
- this.owner = owner;
- AddRange (value);
- }
- #region Public Properties
- public int Count {
- get { return object_items.Count; }
- }
- public bool IsReadOnly {
- get { return false; }
- }
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public virtual object this [int index] {
- get {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- return object_items[index];
- }
- set {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- if (value == null)
- throw new ArgumentNullException ("value");
-
- #if NET_2_0
- //UIA Framework event: Item Removed
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, index));
- #endif
- object_items[index] = value;
-
- #if NET_2_0
- //UIA Framework event: Item Added
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, index));
- #endif
- owner.CollectionChanged ();
- }
- }
- bool ICollection.IsSynchronized {
- get { return false; }
- }
- object ICollection.SyncRoot {
- get { return this; }
- }
- bool IList.IsFixedSize {
- get { return false; }
- }
- #endregion Public Properties
-
- #region Public Methods
- public int Add (object item)
- {
- int idx;
- idx = AddItem (item);
- owner.CollectionChanged ();
-
- // If we are sorted, the item probably moved indexes, get the real one
- if (owner.sorted)
- return this.IndexOf (item);
-
- return idx;
- }
- public void AddRange (object[] items)
- {
- AddItems (items);
- }
- public void AddRange (ObjectCollection value)
- {
- AddItems (value);
- }
- internal void AddItems (IList items)
- {
- if (items == null)
- throw new ArgumentNullException ("items");
- #if ONLY_1_1
- foreach (object mi in items)
- if (mi == null)
- throw new ArgumentNullException ("item");
- #endif
- foreach (object mi in items)
- AddItem (mi);
- owner.CollectionChanged ();
- }
- public virtual void Clear ()
- {
- owner.selected_indices.ClearCore ();
- object_items.Clear ();
- owner.CollectionChanged ();
- #if NET_2_0
- //UIA Framework event: Items list cleared
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, -1));
- #endif
- }
- public bool Contains (object value)
- {
- if (value == null)
- throw new ArgumentNullException ("value");
- return object_items.Contains (value);
- }
- #if NET_2_0
- public void CopyTo (object[] destination, int arrayIndex)
- {
- object [] dest = destination;
- #else
- public void CopyTo (object [] dest, int arrayIndex)
- {
- #endif
- object_items.CopyTo (dest, arrayIndex);
- }
- #if NET_2_0
- void ICollection.CopyTo (Array destination, int index)
- {
- Array dest = destination;
- #else
- void ICollection.CopyTo (Array dest, int index)
- {
- #endif
- object_items.CopyTo (dest, index);
- }
- public IEnumerator GetEnumerator ()
- {
- return object_items.GetEnumerator ();
- }
- int IList.Add (object item)
- {
- return Add (item);
- }
- public int IndexOf (object value)
- {
- if (value == null)
- throw new ArgumentNullException ("value");
- return object_items.IndexOf (value);
- }
- public void Insert (int index, object item)
- {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- if (item == null)
- throw new ArgumentNullException ("item");
-
- owner.BeginUpdate ();
- object_items.Insert (index, item);
- owner.CollectionChanged ();
- owner.EndUpdate ();
-
- #if NET_2_0
- //UIA Framework event: Item Added
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, index));
- #endif
- }
- public void Remove (object value)
- {
- if (value == null)
- return;
- int index = IndexOf (value);
- if (index != -1)
- RemoveAt (index);
- }
- public void RemoveAt (int index)
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- owner.selected_indices.Remove (index);
- object_items.RemoveAt (index);
- owner.CollectionChanged ();
-
- #if NET_2_0
- //UIA Framework event: Item Removed
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Remove, index));
- #endif
- }
- #endregion Public Methods
- #region Private Methods
- internal int AddItem (object item)
- {
- if (item == null)
- throw new ArgumentNullException ("item");
- int cnt = object_items.Count;
- object_items.Add (item);
- #if NET_2_0
- //UIA Framework event: Item Added
- OnUIACollectionChangedEvent (new CollectionChangeEventArgs (CollectionChangeAction.Add, cnt));
- #endif
- return cnt;
- }
- internal void Sort ()
- {
- object_items.Sort (new ListObjectComparer ());
- }
- #endregion Private Methods
- }
- public class SelectedIndexCollection : IList, ICollection, IEnumerable
- {
- private ListBox owner;
- ArrayList selection;
- bool sorting_needed; // Selection state retrieval is done sorted - we do it lazyly
- public SelectedIndexCollection (ListBox owner)
- {
- this.owner = owner;
- selection = new ArrayList ();
- }
- #region Public Properties
- [Browsable (false)]
- public int Count {
- get { return selection.Count; }
- }
- public bool IsReadOnly {
- get { return true; }
- }
- public int this [int index] {
- get {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- CheckSorted ();
- return (int)selection [index];
- }
- }
- bool ICollection.IsSynchronized {
- get { return true; }
- }
- bool IList.IsFixedSize{
- get { return true; }
- }
- object ICollection.SyncRoot {
- get { return selection; }
- }
- #endregion Public Properties
- #region Public Methods
- #if NET_2_0
- public
- #else
- internal
- #endif
- void Add (int index)
- {
- if (AddCore (index)) {
- owner.OnSelectedIndexChanged (EventArgs.Empty);
- owner.OnSelectedValueChanged (EventArgs.Empty);
- }
- }
- // Need to separate selection logic from events,
- // since selection changes using keys/mouse handle them their own way
- internal bool AddCore (int index)
- {
- if (selection.Contains (index))
- return false;
- if (index == -1) // Weird MS behaviour
- return false;
- if (index < -1 || index >= owner.Items.Count)
- throw new ArgumentOutOfRangeException ("index");
- if (owner.selection_mode == SelectionMode.None)
- throw new InvalidOperationException ("Cannot call this method when selection mode is SelectionMode.None");
- if (owner.selection_mode == SelectionMode.One && Count > 0) // Unselect previously selected item
- RemoveCore ((int)selection [0]);
- selection.Add (index);
- sorting_needed = true;
- owner.EnsureVisible (index);
- owner.FocusedItem = index;
- owner.InvalidateItem (index);
- return true;
- }
- #if NET_2_0
- public
- #else
- internal
- #endif
- void Clear ()
- {
- if (ClearCore ()) {
- owner.OnSelectedIndexChanged (EventArgs.Empty);
- owner.OnSelectedValueChanged (EventArgs.Empty);
- }
- }
- internal bool ClearCore ()
- {
- if (selection.Count == 0)
- return false;
- foreach (int index in selection)
- owner.InvalidateItem (index);
- selection.Clear ();
- return true;
- }
- public bool Contains (int selectedIndex)
- {
- foreach (int index in selection)
- if (index == selectedIndex)
- return true;
- return false;
- }
- #if NET_2_0
- public void CopyTo (Array destination, int index)
- {
- Array dest = destination;
- #else
- public void CopyTo (Array dest, int index)
- {
- #endif
- CheckSorted ();
- selection.CopyTo (dest, index);
- }
- public IEnumerator GetEnumerator ()
- {
- CheckSorted ();
- return selection.GetEnumerator ();
- }
- // FIXME: Probably we can avoid sorting when calling
- // IndexOf (imagine a scenario where multiple removal of items
- // happens)
- #if NET_2_0
- public
- #else
- internal
- #endif
- void Remove (int index)
- {
- // Separate logic from events here too
- if (RemoveCore (index)) {
- owner.OnSelectedIndexChanged (EventArgs.Empty);
- owner.OnSelectedValueChanged (EventArgs.Empty);
- }
- }
- internal bool RemoveCore (int index)
- {
- int idx = IndexOf (index);
- if (idx == -1)
- return false;
- selection.RemoveAt (idx);
- owner.InvalidateItem (index);
- return true;
- }
- int IList.Add (object value)
- {
- throw new NotSupportedException ();
- }
- void IList.Clear ()
- {
- throw new NotSupportedException ();
- }
- bool IList.Contains (object selectedIndex)
- {
- return Contains ((int)selectedIndex);
- }
- int IList.IndexOf (object selectedIndex)
- {
- return IndexOf ((int) selectedIndex);
- }
- void IList.Insert (int index, object value)
- {
- throw new NotSupportedException ();
- }
- void IList.Remove (object value)
- {
- throw new NotSupportedException ();
- }
- void IList.RemoveAt (int index)
- {
- throw new NotSupportedException ();
- }
- object IList.this[int index]{
- get { return this [index]; }
- set {throw new NotImplementedException (); }
- }
- public int IndexOf (int selectedIndex)
- {
- CheckSorted ();
- for (int i = 0; i < selection.Count; i++)
- if ((int)selection [i] == selectedIndex)
- return i;
- return -1;
- }
- #endregion Public Methods
- internal ArrayList List {
- get {
- CheckSorted ();
- return selection;
- }
- }
- void CheckSorted ()
- {
- if (sorting_needed) {
- sorting_needed = false;
- selection.Sort ();
- }
- }
- }
- public class SelectedObjectCollection : IList, ICollection, IEnumerable
- {
- private ListBox owner;
- public SelectedObjectCollection (ListBox owner)
- {
- this.owner = owner;
- }
- #region Public Properties
- public int Count {
- get { return owner.selected_indices.Count; }
- }
- public bool IsReadOnly {
- get { return true; }
- }
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public object this [int index] {
- get {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException ("Index of out range");
- return owner.items [owner.selected_indices [index]];
- }
- set {throw new NotSupportedException ();}
- }
- bool ICollection.IsSynchronized {
- get { return true; }
- }
- object ICollection.SyncRoot {
- get { return this; }
- }
- bool IList.IsFixedSize {
- get { return true; }
- }
- #endregion Public Properties
- #region Public Methods
- #if NET_2_0
- public void Add (object value)
- {
- if (owner.selection_mode == SelectionMode.None)
- throw new ArgumentException ("Cannot call this method if SelectionMode is SelectionMode.None");
- int idx = owner.items.IndexOf (value);
- if (idx == -1)
- return;
- owner.selected_indices.Add (idx);
- }
- public void Clear ()
- {
- owner.selected_indices.Clear ();
- }
- #endif
- public bool Contains (object selectedObject)
- {
- int idx = owner.items.IndexOf (selectedObject);
- return idx == -1 ? false : owner.selected_indices.Contains (idx);
- }
- #if NET_2_0
- public void CopyTo (Array destination, int index)
- {
- Array dest = destination;
- #else
- public void CopyTo (Array dest, int index)
- {
- #endif
- for (int i = 0; i < Count; i++)
- dest.SetValue (this [i], index++);
- }
- #if NET_2_0
- public void Remove (object value)
- {
- if (value == null)
- return;
- int idx = owner.items.IndexOf (value);
- if (idx == -1)
- return;
- owner.selected_indices.Remove (idx);
- }
- #endif
- int IList.Add (object value)
- {
- throw new NotSupportedException ();
- }
- void IList.Clear ()
- {
- throw new NotSupportedException ();
- }
- void IList.Insert (int index, object value)
- {
- throw new NotSupportedException ();
- }
- void IList.Remove (object value)
- {
- throw new NotSupportedException ();
- }
- void IList.RemoveAt (int index)
- {
- throw new NotSupportedException ();
- }
-
- public int IndexOf (object selectedObject)
- {
- int idx = owner.items.IndexOf (selectedObject);
- return idx == -1 ? -1 : owner.selected_indices.IndexOf (idx);
- }
- public IEnumerator GetEnumerator ()
- {
- //FIXME: write an enumerator that uses selection.GetEnumerator
- // so that invalidation is write on selection changes
- object [] items = new object [Count];
- for (int i = 0; i < Count; i++) {
- items [i] = owner.items [owner.selected_indices [i]];
- }
- return items.GetEnumerator ();
- }
- #endregion Public Methods
- }
- }
- }
|