| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733 |
- //#########################################################################################
- //★★★★★★★ http://www.cnpopsoft.com [华普软件] ★★★★★★★
- //★★★★★★★ 华普软件 - VB & C#.NET 专业论文与源码荟萃! ★★★★★★★
- //#########################################################################################
- /*
- * Copyright ?2005, Mathew Hall
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- */
- using System;
- using System.Collections;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Windows.Forms;
- using XPTable.Editors;
- using XPTable.Events;
- using XPTable.Models;
- using XPTable.Renderers;
- using XPTable.Sorting;
- using XPTable.Themes;
- using XPTable.Win32;
- namespace XPTable.Models
- {
- /// <summary>
- /// Summary description for Table.
- /// </summary>
- [DesignTimeVisible(true),
- ToolboxItem(true),
- ToolboxBitmap(typeof(Table))]
- public class Table : Control, ISupportInitialize
- {
- #region Event Handlers
- #region Cells
- /// <summary>
- /// Occurs when the value of a Cells property changes
- /// </summary>
- public event CellEventHandler CellPropertyChanged;
- #region Focus
- /// <summary>
- /// Occurs when a Cell gains focus
- /// </summary>
- public event CellFocusEventHandler CellGotFocus;
- /// <summary>
- /// Occurs when a Cell loses focus
- /// </summary>
- public event CellFocusEventHandler CellLostFocus;
- #endregion
- #region Keys
- /// <summary>
- /// Occurs when a key is pressed when a Cell has focus
- /// </summary>
- public event CellKeyEventHandler CellKeyDown;
- /// <summary>
- /// Occurs when a key is released when a Cell has focus
- /// </summary>
- public event CellKeyEventHandler CellKeyUp;
- #endregion
- #region Mouse
- /// <summary>
- /// Occurs when the mouse pointer enters a Cell
- /// </summary>
- public event CellMouseEventHandler CellMouseEnter;
- /// <summary>
- /// Occurs when the mouse pointer leaves a Cell
- /// </summary>
- public event CellMouseEventHandler CellMouseLeave;
- /// <summary>
- /// Occurs when a mouse pointer is over a Cell and a mouse button is pressed
- /// </summary>
- public event CellMouseEventHandler CellMouseDown;
- /// <summary>
- /// Occurs when a mouse pointer is over a Cell and a mouse button is released
- /// </summary>
- public event CellMouseEventHandler CellMouseUp;
- /// <summary>
- /// Occurs when a mouse pointer is moved over a Cell
- /// </summary>
- public event CellMouseEventHandler CellMouseMove;
- /// <summary>
- /// Occurs when the mouse pointer hovers over a Cell
- /// </summary>
- public event CellMouseEventHandler CellMouseHover;
- /// <summary>
- /// Occurs when a Cell is clicked
- /// </summary>
- public event CellMouseEventHandler CellClick;
- /// <summary>
- /// Occurs when a Cell is double-clicked
- /// </summary>
- public event CellMouseEventHandler CellDoubleClick;
- #endregion
- #region Buttons
- /// <summary>
- /// Occurs when a Cell's button is clicked
- /// </summary>
- public event CellButtonEventHandler CellButtonClicked;
- #endregion
- #region CheckBox
- /// <summary>
- /// Occurs when a Cell's Checked value changes
- /// </summary>
- public event CellCheckBoxEventHandler CellCheckChanged;
- #endregion
- #endregion
- #region Column
- /// <summary>
- /// Occurs when a Column's property changes
- /// </summary>
- public event ColumnEventHandler ColumnPropertyChanged;
- #endregion
- #region Column Headers
- /// <summary>
- /// Occurs when the mouse pointer enters a Column Header
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseEnter;
- /// <summary>
- /// Occurs when the mouse pointer leaves a Column Header
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseLeave;
- /// <summary>
- /// Occurs when a mouse pointer is over a Column Header and a mouse button is pressed
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseDown;
- /// <summary>
- /// Occurs when a mouse pointer is over a Column Header and a mouse button is released
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseUp;
- /// <summary>
- /// Occurs when a mouse pointer is moved over a Column Header
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseMove;
- /// <summary>
- /// Occurs when the mouse pointer hovers over a Column Header
- /// </summary>
- public event HeaderMouseEventHandler HeaderMouseHover;
- /// <summary>
- /// Occurs when a Column Header is clicked
- /// </summary>
- public event HeaderMouseEventHandler HeaderClick;
- /// <summary>
- /// Occurs when a Column Header is double-clicked
- /// </summary>
- public event HeaderMouseEventHandler HeaderDoubleClick;
- /// <summary>
- /// Occurs when the height of the Column Headers changes
- /// </summary>
- public event EventHandler HeaderHeightChanged;
- #endregion
- #region ColumnModel
- /// <summary>
- /// Occurs when the value of the Table's ColumnModel property changes
- /// </summary>
- public event EventHandler ColumnModelChanged;
-
- /// <summary>
- /// Occurs when a Column is added to the ColumnModel
- /// </summary>
- public event ColumnModelEventHandler ColumnAdded;
- /// <summary>
- /// Occurs when a Column is removed from the ColumnModel
- /// </summary>
- public event ColumnModelEventHandler ColumnRemoved;
- #endregion
- #region Editing
- /// <summary>
- /// Occurs when the Table begins editing a Cell
- /// </summary>
- public event CellEditEventHandler BeginEditing;
- /// <summary>
- /// Occurs when the Table stops editing a Cell
- /// </summary>
- public event CellEditEventHandler EditingStopped;
- /// <summary>
- /// Occurs when the editing of a Cell is cancelled
- /// </summary>
- public event CellEditEventHandler EditingCancelled;
- #endregion
- #region Rows
- /// <summary>
- /// Occurs when a Cell is added to a Row
- /// </summary>
- public event RowEventHandler CellAdded;
- /// <summary>
- /// Occurs when a Cell is removed from a Row
- /// </summary>
- public event RowEventHandler CellRemoved;
- /// <summary>
- /// Occurs when the value of a Rows property changes
- /// </summary>
- public event RowEventHandler RowPropertyChanged;
- #endregion
- #region Sorting
- /// <summary>
- /// Occurs when a Column is about to be sorted
- /// </summary>
- public event ColumnEventHandler BeginSort;
- /// <summary>
- /// Occurs after a Column has finished sorting
- /// </summary>
- public event ColumnEventHandler EndSort;
- #endregion
- #region Painting
- /// <summary>
- /// Occurs before a Cell is painted
- /// </summary>
- public event PaintCellEventHandler BeforePaintCell;
- /// <summary>
- /// Occurs after a Cell is painted
- /// </summary>
- public event PaintCellEventHandler AfterPaintCell;
- /// <summary>
- /// Occurs before a Column header is painted
- /// </summary>
- public event PaintHeaderEventHandler BeforePaintHeader;
- /// <summary>
- /// Occurs after a Column header is painted
- /// </summary>
- public event PaintHeaderEventHandler AfterPaintHeader;
- #endregion
- #region TableModel
- /// <summary>
- /// Occurs when the value of the Table's TableModel property changes
- /// </summary>
- public event EventHandler TableModelChanged;
-
- /// <summary>
- /// Occurs when a Row is added into the TableModel
- /// </summary>
- public event TableModelEventHandler RowAdded;
- /// <summary>
- /// Occurs when a Row is removed from the TableModel
- /// </summary>
- public event TableModelEventHandler RowRemoved;
- /// <summary>
- /// Occurs when the value of the TableModel Selection property changes
- /// </summary>
- public event SelectionEventHandler SelectionChanged;
- /// <summary>
- /// Occurs when the value of the RowHeight property changes
- /// </summary>
- public event EventHandler RowHeightChanged;
- #endregion
- #endregion
- #region Class Data
-
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- #region Border
- /// <summary>
- /// The style of the Table's border
- /// </summary>
- private BorderStyle borderStyle;
- #endregion
- #region Cells
- /// <summary>
- /// The last known cell position that the mouse was over
- /// </summary>
- private CellPos lastMouseCell;
- /// <summary>
- /// The last known cell position that the mouse's left
- /// button was pressed in
- /// </summary>
- private CellPos lastMouseDownCell;
- /// <summary>
- /// The position of the Cell that currently has focus
- /// </summary>
- private CellPos focusedCell;
- /// <summary>
- /// The Cell that is currently being edited
- /// </summary>
- private CellPos editingCell;
- /// <summary>
- /// The ICellEditor that is currently being used to edit a Cell
- /// </summary>
- private ICellEditor curentCellEditor;
- /// <summary>
- /// The action that must be performed on a Cell to start editing
- /// </summary>
- private EditStartAction editStartAction;
- /// <summary>
- /// The key that must be pressed for editing to start when
- /// editStartAction is set to EditStartAction.CustomKey
- /// </summary>
- private Keys customEditKey;
- /// <summary>
- /// The amount of time (in milliseconds) that that the
- /// mouse pointer must hover over a Cell or Column Header before
- /// a MouseHover event is raised
- /// </summary>
- private int hoverTime;
- /// <summary>
- /// A TRACKMOUSEEVENT used to set the hoverTime
- /// </summary>
- private TRACKMOUSEEVENT trackMouseEvent;
- #endregion
- #region Columns
- /// <summary>
- /// The ColumnModel of the Table
- /// </summary>
- private ColumnModel columnModel;
- /// <summary>
- /// Whether the Table supports column resizing
- /// </summary>
- private bool columnResizing;
- /// <summary>
- /// The index of the column currently being resized
- /// </summary>
- private int resizingColumnIndex;
- /// <summary>
- /// The x coordinate of the currently resizing column
- /// </summary>
- private int resizingColumnAnchor;
- /// <summary>
- /// The horizontal distance between the resize starting
- /// point and the right edge of the resizing column
- /// </summary>
- private int resizingColumnOffset;
- /// <summary>
- /// The width that the resizing column will be set to
- /// once column resizing is finished
- /// </summary>
- private int resizingColumnWidth;
- /// <summary>
- /// The index of the current pressed column
- /// </summary>
- private int pressedColumn;
- /// <summary>
- /// The index of the current "hot" column
- /// </summary>
- private int hotColumn;
- /// <summary>
- /// The index of the last sorted column
- /// </summary>
- private int lastSortedColumn;
- /// <summary>
- /// The Color of a sorted Column's background
- /// </summary>
- private Color sortedColumnBackColor;
- #endregion
- #region Grid
- /// <summary>
- /// Indicates whether grid lines appear between the rows and columns
- /// containing the rows and cells in the Table
- /// </summary>
- private GridLines gridLines;
- /// <summary>
- /// The color of the grid lines
- /// </summary>
- private Color gridColor;
- /// <summary>
- /// The line style of the grid lines
- /// </summary>
- private GridLineStyle gridLineStyle;
- #endregion
- #region Header
- /// <summary>
- /// The styles of the column headers
- /// </summary>
- private ColumnHeaderStyle headerStyle;
- /// <summary>
- /// The Renderer used to paint the column headers
- /// </summary>
- private HeaderRenderer headerRenderer;
- /// <summary>
- /// The font used to draw the text in the column header
- /// </summary>
- private Font headerFont;
- /// <summary>
- /// The ContextMenu for the column headers
- /// </summary>
- private HeaderContextMenu headerContextMenu;
- #endregion
- #region Items
- /// <summary>
- /// The TableModel of the Table
- /// </summary>
- private TableModel tableModel;
- #endregion
- #region Scrollbars
- /// <summary>
- /// Indicates whether the Table will allow the user to scroll to any
- /// columns or rows placed outside of its visible boundaries
- /// </summary>
- private bool scrollable;
- /// <summary>
- /// The Table's horizontal ScrollBar
- /// </summary>
- private HScrollBar hScrollBar;
- /// <summary>
- /// The Table's vertical ScrollBar
- /// </summary>
- private VScrollBar vScrollBar;
- #endregion
- #region Selection
- /// <summary>
- /// Specifies whether rows and cells can be selected
- /// </summary>
- private bool allowSelection;
- /// <summary>
- /// Specifies whether multiple rows and cells can be selected
- /// </summary>
- private bool multiSelect;
- /// <summary>
- /// Specifies whether clicking a row selects all its cells
- /// </summary>
- private bool fullRowSelect;
- /// <summary>
- /// Specifies whether the selected rows and cells in the Table remain
- /// highlighted when the Table loses focus
- /// </summary>
- private bool hideSelection;
- /// <summary>
- /// The background color of selected rows and cells
- /// </summary>
- private Color selectionBackColor;
- /// <summary>
- /// The foreground color of selected rows and cells
- /// </summary>
- private Color selectionForeColor;
- /// <summary>
- /// The background color of selected rows and cells when the Table
- /// doesn't have focus
- /// </summary>
- private Color unfocusedSelectionBackColor;
- /// <summary>
- /// The foreground color of selected rows and cells when the Table
- /// doesn't have focus
- /// </summary>
- private Color unfocusedSelectionForeColor;
- /// <summary>
- /// Determines how selected Cells are hilighted
- /// </summary>
- private SelectionStyle selectionStyle;
- #endregion
- #region Table
- /// <summary>
- /// The state of the table
- /// </summary>
- private TableState tableState;
- /// <summary>
- /// Is the Table currently initialising
- /// </summary>
- private bool init;
- /// <summary>
- /// The number of times BeginUpdate has been called
- /// </summary>
- private int beginUpdateCount;
- /// <summary>
- /// The ToolTip used by the Table to display cell and column tooltips
- /// </summary>
- private ToolTip toolTip;
- /// <summary>
- /// The alternating row background color
- /// </summary>
- private Color alternatingRowColor;
- /// <summary>
- /// The text displayed in the Table when it has no data to display
- /// </summary>
- private string noItemsText;
- /// <summary>
- /// Specifies whether the Table is being used as a preview Table
- /// in a ColumnColection editor
- /// </summary>
- private bool preview;
- /*/// <summary>
- /// Specifies whether pressing the Tab key while editing moves the
- /// editor to the next available cell
- /// </summary>
- private bool tabMovesEditor;*/
- #endregion
- #endregion
- #region Constructor
- /// <summary>
- /// Initializes a new instance of the Table class with default settings
- /// </summary>
- public Table()
- {
- // starting setup
- this.init = true;
-
- // This call is required by the Windows.Forms Form Designer.
- components = new System.ComponentModel.Container();
- //
- this.SetStyle(ControlStyles.UserPaint, true);
- this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- this.SetStyle(ControlStyles.DoubleBuffer, true);
- this.SetStyle(ControlStyles.ResizeRedraw, true);
- this.SetStyle(ControlStyles.Selectable, true);
- this.TabStop = true;
- this.Size = new Size(150, 150);
- this.BackColor = Color.White;
- //
- this.columnModel = null;
- this.tableModel = null;
- // header
- this.headerStyle = ColumnHeaderStyle.Clickable;
- this.headerFont = this.Font;
- this.headerRenderer = new XPHeaderRenderer();
- //this.headerRenderer = new GradientHeaderRenderer();
- //this.headerRenderer = new FlatHeaderRenderer();
- this.headerRenderer.Font = this.headerFont;
- this.headerContextMenu = new HeaderContextMenu();
-
- this.columnResizing = true;
- this.resizingColumnIndex = -1;
- this.resizingColumnWidth = -1;
- this.hotColumn = -1;
- this.pressedColumn = -1;
- this.lastSortedColumn = -1;
- this.sortedColumnBackColor = Color.WhiteSmoke;
- // borders
- this.borderStyle = BorderStyle.Fixed3D;
- // scrolling
- this.scrollable = true;
- this.hScrollBar = new HScrollBar();
- this.hScrollBar.Visible = false;
- this.hScrollBar.Location = new Point(this.BorderWidth, this.Height - this.BorderWidth - SystemInformation.HorizontalScrollBarHeight);
- this.hScrollBar.Width = this.Width - (this.BorderWidth * 2) - SystemInformation.VerticalScrollBarWidth;
- this.hScrollBar.Scroll += new ScrollEventHandler(this.OnHorizontalScroll);
- this.Controls.Add(this.hScrollBar);
- this.vScrollBar = new VScrollBar();
- this.vScrollBar.Visible = false;
- this.vScrollBar.Location = new Point(this.Width - this.BorderWidth - SystemInformation.VerticalScrollBarWidth, this.BorderWidth);
- this.vScrollBar.Height = this.Height - (this.BorderWidth * 2) - SystemInformation.HorizontalScrollBarHeight;
- this.vScrollBar.Scroll += new ScrollEventHandler(this.OnVerticalScroll);
- this.Controls.Add(this.vScrollBar);
- //
- this.gridLines = GridLines.None;;
- this.gridColor = SystemColors.Control;
- this.gridLineStyle = GridLineStyle.Solid;
- this.allowSelection = true;
- this.multiSelect = false;
- this.fullRowSelect = false;
- this.hideSelection = false;
- this.selectionBackColor = SystemColors.Highlight;
- this.selectionForeColor = SystemColors.HighlightText;
- this.unfocusedSelectionBackColor = SystemColors.Control;
- this.unfocusedSelectionForeColor = SystemColors.ControlText;
- this.selectionStyle = SelectionStyle.ListView;
- this.alternatingRowColor = Color.Transparent;
- // current table state
- this.tableState = TableState.Normal;
- this.lastMouseCell = new CellPos(-1, -1);
- this.lastMouseDownCell = new CellPos(-1, -1);
- this.focusedCell = new CellPos(-1, -1);
- this.hoverTime = 1000;
- this.trackMouseEvent = null;
- this.ResetMouseEventArgs();
- this.toolTip = new ToolTip(this.components);
- this.toolTip.Active = false;
- this.toolTip.InitialDelay = 1000;
- this.noItemsText = "There are no items in this view";
- this.editingCell = new CellPos(-1, -1);
- this.curentCellEditor = null;
- this.editStartAction = EditStartAction.DoubleClick;
- this.customEditKey = Keys.F5;
- //this.tabMovesEditor = true;
- // finished setting up
- this.beginUpdateCount = 0;
- this.init = false;
- this.preview = false;
- }
- #endregion
- #region Methods
- #region Coordinate Translation
- #region ClientToDisplayRect
-
- /// <summary>
- /// Computes the location of the specified client point into coordinates
- /// relative to the display rectangle
- /// </summary>
- /// <param name="x">The client x coordinate to convert</param>
- /// <param name="y">The client y coordinate to convert</param>
- /// <returns>A Point that represents the converted coordinates (x, y),
- /// relative to the display rectangle</returns>
- public Point ClientToDisplayRect(int x, int y)
- {
- int xPos = x - this.BorderWidth;
- if (this.HScroll)
- {
- xPos += this.hScrollBar.Value;
- }
- int yPos = y - this.BorderWidth;
- if (this.VScroll)
- {
- yPos += this.TopIndex * this.RowHeight;
- }
- return new Point(xPos, yPos);
- }
- /// <summary>
- /// Computes the location of the specified client point into coordinates
- /// relative to the display rectangle
- /// </summary>
- /// <param name="p">The client coordinate Point to convert</param>
- /// <returns>A Point that represents the converted Point, p,
- /// relative to the display rectangle</returns>
- public Point ClientToDisplayRect(Point p)
- {
- return this.ClientToDisplayRect(p.X, p.Y);
- }
- /// <summary>
- /// Converts the location of the specified Rectangle into coordinates
- /// relative to the display rectangle
- /// </summary>
- /// <param name="rect">The Rectangle to convert whose location is in
- /// client coordinates</param>
- /// <returns>A Rectangle that represents the converted Rectangle, rect,
- /// relative to the display rectangle</returns>
- public Rectangle ClientToDisplayRect(Rectangle rect)
- {
- return new Rectangle(this.ClientToDisplayRect(rect.Location), rect.Size);
- }
- #endregion
- #region DisplayRectToClient
- /// <summary>
- /// Computes the location of the specified point relative to the display
- /// rectangle point into client coordinates
- /// </summary>
- /// <param name="x">The x coordinate to convert relative to the display rectangle</param>
- /// <param name="y">The y coordinate to convert relative to the display rectangle</param>
- /// <returns>A Point that represents the converted coordinates (x, y) relative to
- /// the display rectangle in client coordinates</returns>
- public Point DisplayRectToClient(int x, int y)
- {
- int xPos = x + this.BorderWidth;
- if (this.HScroll)
- {
- xPos -= this.hScrollBar.Value;
- }
- int yPos = y + this.BorderWidth;
- if (this.VScroll)
- {
- yPos -= this.TopIndex * this.RowHeight;
- }
- return new Point(xPos, yPos);
- }
- /// <summary>
- /// Computes the location of the specified point relative to the display
- /// rectangle into client coordinates
- /// </summary>
- /// <param name="p">The point relative to the display rectangle to convert</param>
- /// <returns>A Point that represents the converted Point relative to
- /// the display rectangle, p, in client coordinates</returns>
- public Point DisplayRectToClient(Point p)
- {
- return this.DisplayRectToClient(p.X, p.Y);
- }
- /// <summary>
- /// Converts the location of the specified Rectangle relative to the display
- /// rectangle into client coordinates
- /// </summary>
- /// <param name="rect">The Rectangle to convert whose location is relative to
- /// the display rectangle</param>
- /// <returns>A Rectangle that represents the converted Rectangle relative to
- /// the display rectangle, rect, in client coordinates</returns>
- public Rectangle DisplayRectToClient(Rectangle rect)
- {
- return new Rectangle(this.DisplayRectToClient(rect.Location), rect.Size);
- }
- #endregion
- #region Cells
- /// <summary>
- /// Returns the Cell at the specified client coordinates
- /// </summary>
- /// <param name="x">The client x coordinate of the Cell</param>
- /// <param name="y">The client y coordinate of the Cell</param>
- /// <returns>The Cell at the specified client coordinates, or
- /// null if it does not exist</returns>
- public Cell CellAt(int x, int y)
- {
- int row = this.RowIndexAt(x, y);
- int column = this.ColumnIndexAt(x, y);
- // return null if the row or column don't exist
- if (row == -1 || row >= this.TableModel.Rows.Count || column == -1 || column >= this.TableModel.Rows[row].Cells.Count)
- {
- return null;
- }
- return this.TableModel[row, column];
- }
- /// <summary>
- /// Returns the Cell at the specified client Point
- /// </summary>
- /// <param name="p">The point of interest</param>
- /// <returns>The Cell at the specified client Point,
- /// or null if not found</returns>
- public Cell CellAt(Point p)
- {
- return this.CellAt(p.X, p.Y);
- }
- /// <summary>
- /// Returns a Rectangle that specifies the size and location the cell at
- /// the specified row and column indexes in client coordinates
- /// </summary>
- /// <param name="row">The index of the row that contains the cell</param>
- /// <param name="column">The index of the column that contains the cell</param>
- /// <returns>A Rectangle that specifies the size and location the cell at
- /// the specified row and column indexes in client coordinates</returns>
- public Rectangle CellRect(int row, int column)
- {
- // return null if the row or column don't exist
- if (row == -1 || row >= this.TableModel.Rows.Count || column == -1 || column >= this.TableModel.Rows[row].Cells.Count)
- {
- return Rectangle.Empty;
- }
-
- Rectangle columnRect = this.ColumnRect(column);
- if (columnRect == Rectangle.Empty)
- {
- return columnRect;
- }
- Rectangle rowRect = this.RowRect(row);
- if (rowRect == Rectangle.Empty)
- {
- return rowRect;
- }
- return new Rectangle(columnRect.X, rowRect.Y, columnRect.Width, rowRect.Height);
- }
- /// <summary>
- /// Returns a Rectangle that specifies the size and location the cell at
- /// the specified cell position in client coordinates
- /// </summary>
- /// <param name="cellPos">The position of the cell</param>
- /// <returns>A Rectangle that specifies the size and location the cell at
- /// the specified cell position in client coordinates</returns>
- public Rectangle CellRect(CellPos cellPos)
- {
- return this.CellRect(cellPos.Row, cellPos.Column);
- }
- /// <summary>
- /// Returns a Rectangle that specifies the size and location of the
- /// specified cell in client coordinates
- /// </summary>
- /// <param name="cell">The cell whose bounding rectangle is to be retrieved</param>
- /// <returns>A Rectangle that specifies the size and location the specified
- /// cell in client coordinates</returns>
- public Rectangle CellRect(Cell cell)
- {
- if (cell == null || cell.Row == null || cell.InternalIndex == -1)
- {
- return Rectangle.Empty;
- }
- if (this.TableModel == null || this.ColumnModel == null)
- {
- return Rectangle.Empty;
- }
- int row = this.TableModel.Rows.IndexOf(cell.Row);
- int col = cell.InternalIndex;
- return this.CellRect(row, col);
- }
- /// <summary>
- /// Returns whether Cell at the specified row and column indexes
- /// is not null
- /// </summary>
- /// <param name="row">The row index of the cell</param>
- /// <param name="column">The column index of the cell</param>
- /// <returns>True if the cell at the specified row and column indexes
- /// is not null, otherwise false</returns>
- protected internal bool IsValidCell(int row, int column)
- {
- if (this.TableModel != null && this.ColumnModel != null)
- {
- if (row >= 0 && row < this.TableModel.Rows.Count)
- {
- if (column >= 0 && column < this.ColumnModel.Columns.Count)
- {
- return (this.TableModel.Rows[row].Cells[column] != null);
- }
- }
- }
- return false;
- }
- /// <summary>
- /// Returns whether Cell at the specified cell position is not null
- /// </summary>
- /// <param name="cellPos">The position of the cell</param>
- /// <returns>True if the cell at the specified cell position is not
- /// null, otherwise false</returns>
- protected internal bool IsValidCell(CellPos cellPos)
- {
- return this.IsValidCell(cellPos.Row, cellPos.Column);
- }
- /// <summary>
- /// Returns a CellPos that specifies the next Cell that is visible
- /// and enabled from the specified Cell
- /// </summary>
- /// <param name="start">A CellPos that specifies the Cell to start
- /// searching from</param>
- /// <param name="wrap">Specifies whether to move to the start of the
- /// next Row when the end of the current Row is reached</param>
- /// <param name="forward">Specifies whether the search should travel
- /// in a forward direction (top to bottom, left to right) through the Cells</param>
- /// <param name="includeStart">Indicates whether the specified starting
- /// Cell is included in the search</param>
- /// <param name="checkOtherCellsInRow">Specifies whether all Cells in
- /// the Row should be included in the search</param>
- /// <returns>A CellPos that specifies the next Cell that is visible
- /// and enabled, or CellPos.Empty if there are no Cells that are visible
- /// and enabled</returns>
- protected CellPos FindNextVisibleEnabledCell(CellPos start, bool wrap, bool forward, bool includeStart, bool checkOtherCellsInRow)
- {
- if (this.ColumnCount == 0 || this.RowCount == 0)
- {
- return CellPos.Empty;
- }
-
- int startRow = start.Row != -1 ? start.Row : 0;
- int startCol = start.Column != -1 ? start.Column : 0;
- bool first = true;
-
- if (forward)
- {
- for (int i=startRow; i<this.RowCount; i++)
- {
- int j = (first || !checkOtherCellsInRow ? startCol : 0);
-
- for (; j<this.TableModel.Rows[i].Cells.Count; j++)
- {
- if (i == startRow && j == startCol)
- {
- if (!first)
- {
- return CellPos.Empty;
- }
- first = false;
- if (!includeStart)
- {
- if (!checkOtherCellsInRow)
- {
- break;
- }
- continue;
- }
- }
-
- if (this.IsValidCell(i, j) && this.IsValidColumn(j) && this.TableModel[i, j].Enabled && this.ColumnModel.Columns[j].Enabled && this.ColumnModel.Columns[j].Visible)
- {
- return new CellPos(i, j);
- }
- if (!checkOtherCellsInRow)
- {
- continue;
- }
- }
- if (wrap)
- {
- if (i+1 == this.TableModel.Rows.Count)
- {
- i = -1;
- }
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- for (int i=startRow; i>=0; i--)
- {
- int j = (first || !checkOtherCellsInRow ? startCol : this.TableModel.Rows[i].Cells.Count);
-
- for (; j>=0; j--)
- {
- if (i == startRow && j == startCol)
- {
- if (!first)
- {
- return CellPos.Empty;
- }
- first = false;
- if (!includeStart)
- {
- if (!checkOtherCellsInRow)
- {
- break;
- }
- continue;
- }
- }
-
- if (this.IsValidCell(i, j) && this.IsValidColumn(j) && this.TableModel[i, j].Enabled && this.ColumnModel.Columns[j].Enabled && this.ColumnModel.Columns[j].Visible)
- {
- return new CellPos(i, j);
- }
- if (!checkOtherCellsInRow)
- {
- continue;
- }
- }
- if (wrap)
- {
- if (i-1 == -1)
- {
- i = this.TableModel.Rows.Count;
- }
- }
- else
- {
- break;
- }
- }
- }
- return CellPos.Empty;
- }
- /// <summary>
- /// Returns a CellPos that specifies the next Cell that able to be
- /// edited from the specified Cell
- /// </summary>
- /// <param name="start">A CellPos that specifies the Cell to start
- /// searching from</param>
- /// <param name="wrap">Specifies whether to move to the start of the
- /// next Row when the end of the current Row is reached</param>
- /// <param name="forward">Specifies whether the search should travel
- /// in a forward direction (top to bottom, left to right) through the Cells</param>
- /// <param name="includeStart">Indicates whether the specified starting
- /// Cell is included in the search</param>
- /// <returns>A CellPos that specifies the next Cell that is able to
- /// be edited, or CellPos.Empty if there are no Cells that editable</returns>
- protected CellPos FindNextEditableCell(CellPos start, bool wrap, bool forward, bool includeStart)
- {
- if (this.ColumnCount == 0 || this.RowCount == 0)
- {
- return CellPos.Empty;
- }
-
- int startRow = start.Row != -1 ? start.Row : 0;
- int startCol = start.Column != -1 ? start.Column : 0;
- bool first = true;
-
- if (forward)
- {
- for (int i=startRow; i<this.RowCount; i++)
- {
- int j = (first ? startCol : 0);
-
- for (; j<this.TableModel.Rows[i].Cells.Count; j++)
- {
- if (i == startRow && j == startCol)
- {
- if (!first)
- {
- return CellPos.Empty;
- }
- first = false;
- if (!includeStart)
- {
- continue;
- }
- }
-
- if (this.IsValidCell(i, j) && this.IsValidColumn(j) && this.TableModel[i, j].Editable && this.ColumnModel.Columns[j].Editable)
- {
- return new CellPos(i, j);
- }
- }
- if (wrap)
- {
- if (i+1 == this.TableModel.Rows.Count)
- {
- i = -1;
- }
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- for (int i=startRow; i>=0; i--)
- {
- int j = (first ? startCol : this.TableModel.Rows[i].Cells.Count);
-
- for (; j>=0; j--)
- {
- if (i == startRow && j == startCol)
- {
- if (!first)
- {
- return CellPos.Empty;
- }
- first = false;
- if (!includeStart)
- {
- continue;
- }
- }
-
- if (this.IsValidCell(i, j) && this.IsValidColumn(j) && this.TableModel[i, j].Editable && this.ColumnModel.Columns[j].Editable)
- {
- return new CellPos(i, j);
- }
- }
- if (wrap)
- {
- if (i-1 == -1)
- {
- i = this.TableModel.Rows.Count;
- }
- }
- else
- {
- break;
- }
- }
- }
- return CellPos.Empty;
- }
- #endregion
- #region Columns
- /// <summary>
- /// Returns the index of the Column at the specified client coordinates
- /// </summary>
- /// <param name="x">The client x coordinate of the Column</param>
- /// <param name="y">The client y coordinate of the Column</param>
- /// <returns>The index of the Column at the specified client coordinates, or
- /// -1 if it does not exist</returns>
- public int ColumnIndexAt(int x, int y)
- {
- if (this.ColumnModel == null)
- {
- return -1;
- }
-
- // convert to DisplayRect coordinates before
- // sending to the ColumnModel
- return this.ColumnModel.ColumnIndexAtX(this.hScrollBar.Value + x - this.BorderWidth);
- }
- /// <summary>
- /// Returns the index of the Column at the specified client point
- /// </summary>
- /// <param name="p">The point of interest</param>
- /// <returns>The index of the Column at the specified client point, or
- /// -1 if it does not exist</returns>
- public int ColumnIndexAt(Point p)
- {
- return this.ColumnIndexAt(p.X, p.Y);
- }
- /// <summary>
- /// Returns the bounding rectangle of the specified
- /// column's header in client coordinates
- /// </summary>
- /// <param name="column">The index of the column</param>
- /// <returns>The bounding rectangle of the specified
- /// column's header</returns>
- public Rectangle ColumnHeaderRect(int column)
- {
- if (this.ColumnModel == null)
- {
- return Rectangle.Empty;
- }
-
- Rectangle rect = this.ColumnModel.ColumnHeaderRect(column);
- if (rect == Rectangle.Empty)
- {
- return rect;
- }
- rect.X -= this.hScrollBar.Value - this.BorderWidth;
- rect.Y = this.BorderWidth;
- return rect;
- }
- /// <summary>
- /// Returns the bounding rectangle of the specified
- /// column's header in client coordinates
- /// </summary>
- /// <param name="column">The column</param>
- /// <returns>The bounding rectangle of the specified
- /// column's header</returns>
- public Rectangle ColumnHeaderRect(Column column)
- {
- if (this.ColumnModel == null)
- {
- return Rectangle.Empty;
- }
-
- return this.ColumnHeaderRect(this.ColumnModel.Columns.IndexOf(column));
- }
- /// <summary>
- /// Returns the bounding rectangle of the column at the
- /// specified index in client coordinates
- /// </summary>
- /// <param name="column">The column</param>
- /// <returns>The bounding rectangle of the column at the
- /// specified index</returns>
- public Rectangle ColumnRect(int column)
- {
- if (this.ColumnModel == null)
- {
- return Rectangle.Empty;
- }
-
- Rectangle rect = this.ColumnHeaderRect(column);
- if (rect == Rectangle.Empty)
- {
- return rect;
- }
- rect.Y += this.HeaderHeight;
- rect.Height = this.TotalRowHeight;
- return rect;
- }
- /// <summary>
- /// Returns the bounding rectangle of the specified column
- /// in client coordinates
- /// </summary>
- /// <param name="column">The column</param>
- /// <returns>The bounding rectangle of the specified
- /// column</returns>
- public Rectangle ColumnRect(Column column)
- {
- if (this.ColumnModel == null)
- {
- return Rectangle.Empty;
- }
-
- return this.ColumnRect(this.ColumnModel.Columns.IndexOf(column));
- }
- #endregion
- #region Rows
- /// <summary>
- /// Returns the index of the Row at the specified client coordinates
- /// </summary>
- /// <param name="x">The client x coordinate of the Row</param>
- /// <param name="y">The client y coordinate of the Row</param>
- /// <returns>The index of the Row at the specified client coordinates, or
- /// -1 if it does not exist</returns>
- public int RowIndexAt(int x, int y)
- {
- if (this.TableModel == null)
- {
- return -1;
- }
- if (this.HeaderStyle != ColumnHeaderStyle.None)
- {
- y -= this.HeaderHeight;
- }
- y -= this.BorderWidth;
- if (y < 0)
- {
- return -1;
- }
-
- if (this.VScroll)
- {
- y += this.TopIndex * this.RowHeight;
- }
- return this.TableModel.RowIndexAt(y);
- }
- /// <summary>
- /// Returns the index of the Row at the specified client point
- /// </summary>
- /// <param name="p">The point of interest</param>
- /// <returns>The index of the Row at the specified client point, or
- /// -1 if it does not exist</returns>
- public int RowIndexAt(Point p)
- {
- return this.RowIndexAt(p.X, p.Y);
- }
- /// <summary>
- /// Returns the bounding rectangle of the row at the
- /// specified index in client coordinates
- /// </summary>
- /// <param name="row">The index of the row</param>
- /// <returns>The bounding rectangle of the row at the
- /// specified index</returns>
- public Rectangle RowRect(int row)
- {
- if (this.TableModel == null || this.ColumnModel == null || row == -1 || row > this.TableModel.Rows.Count)
- {
- return Rectangle.Empty;
- }
-
- Rectangle rect = new Rectangle();
- rect.X = this.DisplayRectangle.X;
- rect.Y = this.BorderWidth + ((row - this.TopIndex) * this.RowHeight);
-
- rect.Width = this.ColumnModel.VisibleColumnsWidth;
- rect.Height = this.RowHeight;
- if (this.HeaderStyle != ColumnHeaderStyle.None)
- {
- rect.Y += this.HeaderHeight;
- }
- return rect;
- }
- /// <summary>
- /// Returns the bounding rectangle of the specified row
- /// in client coordinates
- /// </summary>
- /// <param name="row">The row</param>
- /// <returns>The bounding rectangle of the specified
- /// row</returns>
- public Rectangle RowRect(Row row)
- {
- if (this.TableModel == null)
- {
- return Rectangle.Empty;
- }
-
- return this.RowRect(this.TableModel.Rows.IndexOf(row));
- }
- #endregion
- #region Hit Tests
- /// <summary>
- /// Returns a TableRegions value that represents the table region at
- /// the specified client coordinates
- /// </summary>
- /// <param name="x">The client x coordinate</param>
- /// <param name="y">The client y coordinate</param>
- /// <returns>A TableRegions value that represents the table region at
- /// the specified client coordinates</returns>
- public TableRegion HitTest(int x, int y)
- {
- if (this.HeaderStyle != ColumnHeaderStyle.None && this.HeaderRectangle.Contains(x, y))
- {
- return TableRegion.ColumnHeader;
- }
- else if (this.CellDataRect.Contains(x, y))
- {
- return TableRegion.Cells;
- }
- else if (!this.Bounds.Contains(x, y))
- {
- return TableRegion.NoWhere;
- }
-
- return TableRegion.NonClientArea;
- }
- /// <summary>
- /// Returns a TableRegions value that represents the table region at
- /// the specified client point
- /// </summary>
- /// <param name="p">The point of interest</param>
- /// <returns>A TableRegions value that represents the table region at
- /// the specified client point</returns>
- public TableRegion HitTest(Point p)
- {
- return this.HitTest(p.X, p.Y);
- }
- #endregion
- #endregion
- #region Dispose
- /// <summary>
- /// Releases the unmanaged resources used by the Control and optionally
- /// releases the managed resources
- /// </summary>
- /// <param name="disposing">true to release both managed and unmanaged
- /// resources; false to release only unmanaged resources</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
- /// <summary>
- /// Removes the ColumnModel and TableModel from the Table
- /// </summary>
- public void Clear()
- {
- if (this.ColumnModel != null)
- {
- this.ColumnModel = null;
- }
- if (this.TableModel != null)
- {
- this.TableModel = null;
- }
- }
- #endregion
- #region Editing
- /// <summary>
- /// Records the Cell that is currently being edited and the
- /// ICellEditor used to edit the Cell
- /// </summary>
- /// <param name="cell">The Cell that is currently being edited</param>
- /// <param name="editor">The ICellEditor used to edit the Cell</param>
- private void SetEditingCell(Cell cell, ICellEditor editor)
- {
- this.SetEditingCell(new CellPos(cell.Row.InternalIndex, cell.InternalIndex), editor);
- }
- /// <summary>
- /// Records the Cell that is currently being edited and the
- /// ICellEditor used to edit the Cell
- /// </summary>
- /// <param name="cellPos">The Cell that is currently being edited</param>
- /// <param name="editor">The ICellEditor used to edit the Cell</param>
- private void SetEditingCell(CellPos cellPos, ICellEditor editor)
- {
- this.editingCell = cellPos;
- this.curentCellEditor = editor;
- }
- /// <summary>
- /// Starts editing the Cell at the specified row and column indexes
- /// </summary>
- /// <param name="row">The row index of the Cell to be edited</param>
- /// <param name="column">The column index of the Cell to be edited</param>
- public void EditCell(int row, int column)
- {
- this.EditCell(new CellPos(row, column));
- }
- /// <summary>
- /// Starts editing the Cell at the specified CellPos
- /// </summary>
- /// <param name="cellPos">A CellPos that specifies the Cell to be edited</param>
- public void EditCell(CellPos cellPos)
- {
- // don't bother if the cell doesn't exists or the cell's
- // column is not visible or the cell is not editable
- if (!this.IsValidCell(cellPos) || !this.ColumnModel.Columns[cellPos.Column].Visible || !this.IsCellEditable(cellPos))
- {
- return;
- }
- // check if we're currently editing a cell
- if (this.EditingCell != CellPos.Empty)
- {
- // don't bother if we're already editing the cell.
- // if we're editing a different cell stop editing
- if (this.EditingCell == cellPos)
- {
- return;
- }
- else
- {
- this.EditingCellEditor.StopEditing();
- }
- }
- Cell cell = this.TableModel[cellPos];
- ICellEditor editor = this.ColumnModel.GetCellEditor(cellPos.Column);
- // make sure we have an editor and that the cell
- // and the cell's column are editable
- if (editor == null || !cell.Editable || !this.ColumnModel.Columns[cellPos.Column].Editable)
- {
- return;
- }
- if (this.EnsureVisible(cellPos))
- {
- this.Refresh();
- }
- Rectangle cellRect = this.CellRect(cellPos);
- // give anyone subscribed to the table's BeginEditing
- // event the first chance to cancel editing
- CellEditEventArgs e = new CellEditEventArgs(cell, editor, this, cellPos.Row, cellPos.Column, cellRect);
- this.OnBeginEditing(e);
- //
- if (!e.Cancel)
- {
- // get the editor ready for editing. if PrepareForEditing
- // returns false, someone who subscribed to the editors
- // BeginEdit event has cancelled editing
- if (!editor.PrepareForEditing(cell, this, cellPos, cellRect, e.Handled))
- {
- return;
- }
- // keep track of the editing cell and editor
- // and start editing
- this.editingCell = cellPos;
- this.curentCellEditor = editor;
- editor.StartEditing();
- }
- }
- /*/// <summary>
- /// Stops editing the current Cell and starts editing the next editable Cell
- /// </summary>
- /// <param name="forwards">Specifies whether the editor should traverse
- /// forward when looking for the next editable Cell</param>
- protected internal void EditNextCell(bool forwards)
- {
- if (this.EditingCell == CellPos.Empty)
- {
- return;
- }
-
- CellPos nextCell = this.FindNextEditableCell(this.FocusedCell, true, forwards, false);
- if (nextCell != CellPos.Empty && nextCell != this.EditingCell)
- {
- this.StopEditing();
- this.EditCell(nextCell);
- }
- }*/
- /// <summary>
- /// Stops editing the current Cell and commits any changes
- /// </summary>
- public void StopEditing()
- {
- // don't bother if we're not editing
- if (this.EditingCell == CellPos.Empty)
- {
- return;
- }
- this.EditingCellEditor.StopEditing();
- this.Invalidate(this.RowRect(this.editingCell.Row));
- this.editingCell = CellPos.Empty;
- this.curentCellEditor = null;
- }
- /// <summary>
- /// Cancels editing the current Cell and ignores any changes
- /// </summary>
- public void CancelEditing()
- {
- // don't bother if we're not editing
- if (this.EditingCell == CellPos.Empty)
- {
- return;
- }
- this.EditingCellEditor.CancelEditing();
- this.editingCell = CellPos.Empty;
- this.curentCellEditor = null;
- }
- /// <summary>
- /// Returns whether the Cell at the specified row and column is able
- /// to be edited by the user
- /// </summary>
- /// <param name="row">The row index of the Cell to check</param>
- /// <param name="column">The column index of the Cell to check</param>
- /// <returns>True if the Cell at the specified row and column is able
- /// to be edited by the user, false otherwise</returns>
- public bool IsCellEditable(int row, int column)
- {
- return this.IsCellEditable(new CellPos(row, column));
- }
- /// <summary>
- /// Returns whether the Cell at the specified CellPos is able
- /// to be edited by the user
- /// </summary>
- /// <param name="cellpos">A CellPos that specifies the Cell to check</param>
- /// <returns>True if the Cell at the specified CellPos is able
- /// to be edited by the user, false otherwise</returns>
- public bool IsCellEditable(CellPos cellpos)
- {
- // don't bother if the cell doesn't exists or the cell's
- // column is not visible
- if (!this.IsValidCell(cellpos) || !this.ColumnModel.Columns[cellpos.Column].Visible)
- {
- return false;
- }
- return (this.TableModel[cellpos].Editable &&
- this.ColumnModel.Columns[cellpos.Column].Editable);
- }
- /// <summary>
- /// Returns whether the Cell at the specified row and column is able
- /// to respond to user interaction
- /// </summary>
- /// <param name="row">The row index of the Cell to check</param>
- /// <param name="column">The column index of the Cell to check</param>
- /// <returns>True if the Cell at the specified row and column is able
- /// to respond to user interaction, false otherwise</returns>
- public bool IsCellEnabled(int row, int column)
- {
- return this.IsCellEnabled(new CellPos(row, column));
- }
- /// <summary>
- /// Returns whether the Cell at the specified CellPos is able
- /// to respond to user interaction
- /// </summary>
- /// <param name="cellpos">A CellPos that specifies the Cell to check</param>
- /// <returns>True if the Cell at the specified CellPos is able
- /// to respond to user interaction, false otherwise</returns>
- public bool IsCellEnabled(CellPos cellpos)
- {
- // don't bother if the cell doesn't exists or the cell's
- // column is not visible
- if (!this.IsValidCell(cellpos) || !this.ColumnModel.Columns[cellpos.Column].Visible)
- {
- return false;
- }
- return (this.TableModel[cellpos].Enabled &&
- this.ColumnModel.Columns[cellpos.Column].Enabled);
- }
- #endregion
- #region Invalidate
- /// <summary>
- /// Invalidates the specified Cell
- /// </summary>
- /// <param name="cell">The Cell to be invalidated</param>
- public void InvalidateCell(Cell cell)
- {
- this.InvalidateCell(cell.Row.Index, cell.Index);
- }
- /// <summary>
- /// Invalidates the Cell located at the specified row and column indicies
- /// </summary>
- /// <param name="row">The row index of the Cell to be invalidated</param>
- /// <param name="column">The column index of the Cell to be invalidated</param>
- public void InvalidateCell(int row, int column)
- {
- Rectangle cellRect = this.CellRect(row, column);
- if (cellRect == Rectangle.Empty)
- {
- return;
- }
- if (cellRect.IntersectsWith(this.CellDataRect))
- {
- this.Invalidate(Rectangle.Intersect(this.CellDataRect, cellRect), false);
- }
- }
- /// <summary>
- /// Invalidates the Cell located at the specified CellPos
- /// </summary>
- /// <param name="cellPos">A CellPos that specifies the Cell to be invalidated</param>
- public void InvalidateCell(CellPos cellPos)
- {
- this.InvalidateCell(cellPos.Row, cellPos.Column);
- }
- /// <summary>
- /// Invalidates the specified Row
- /// </summary>
- /// <param name="row">The Row to be invalidated</param>
- public void InvalidateRow(Row row)
- {
- this.InvalidateRow(row.Index);
- }
- /// <summary>
- /// Invalidates the Row located at the specified row index
- /// </summary>
- /// <param name="row">The row index of the Row to be invalidated</param>
- public void InvalidateRow(int row)
- {
- Rectangle rowRect = this.RowRect(row);
- if (rowRect == Rectangle.Empty)
- {
- return;
- }
- if (rowRect.IntersectsWith(this.CellDataRect))
- {
- this.Invalidate(Rectangle.Intersect(this.CellDataRect, rowRect), false);
- }
- }
- /// <summary>
- /// Invalidates the Row located at the specified CellPos
- /// </summary>
- /// <param name="cellPos">A CellPos that specifies the Row to be invalidated</param>
- public void InvalidateRow(CellPos cellPos)
- {
- this.InvalidateRow(cellPos.Row);
- }
- #endregion
- #region Keys
- /// <summary>
- /// Determines whether the specified key is reserved for use by the Table
- /// </summary>
- /// <param name="key">One of the Keys values</param>
- /// <returns>true if the specified key is reserved for use by the Table;
- /// otherwise, false</returns>
- protected internal bool IsReservedKey(Keys key)
- {
- if ((key & Keys.Alt) != Keys.Alt)
- {
- Keys k = key & Keys.KeyCode;
-
- return (k == Keys.Up ||
- k == Keys.Down ||
- k == Keys.Left ||
- k == Keys.Right ||
- k == Keys.PageUp ||
- k == Keys.PageDown ||
- k == Keys.Home ||
- k == Keys.End ||
- k == Keys.Tab);
- }
- return false;
- }
- /// <summary>
- /// Determines whether the specified key is a regular input key or a special
- /// key that requires preprocessing
- /// </summary>
- /// <param name="keyData">One of the Keys values</param>
- /// <returns>true if the specified key is a regular input key; otherwise, false</returns>
- protected override bool IsInputKey(Keys keyData)
- {
- if ((keyData & Keys.Alt) != Keys.Alt)
- {
- Keys key = keyData & Keys.KeyCode;
-
- switch (key)
- {
- case Keys.Up:
- case Keys.Down:
- case Keys.Left:
- case Keys.Right:
- case Keys.Prior:
- case Keys.Next:
- case Keys.End:
- case Keys.Home:
- {
- return true;
- }
- }
- if (base.IsInputKey(keyData))
- {
- return true;
- }
- }
- return false;
- }
- #endregion
- #region Layout
- /// <summary>
- /// Prevents the Table from drawing until the EndUpdate method is called
- /// </summary>
- public void BeginUpdate()
- {
- if (this.IsHandleCreated)
- {
- if (this.beginUpdateCount == 0)
- {
- NativeMethods.SendMessage(this.Handle, 11, 0, 0);
- }
- this.beginUpdateCount++;
- }
- }
- /// <summary>
- /// Resumes drawing of the Table after drawing is suspended by the
- /// BeginUpdate method
- /// </summary>
- public void EndUpdate()
- {
- if (this.beginUpdateCount <= 0)
- {
- return;
- }
-
- this.beginUpdateCount--;
-
- if (this.beginUpdateCount == 0)
- {
- NativeMethods.SendMessage(this.Handle, 11, -1, 0);
-
- this.PerformLayout();
- this.Invalidate(true);
- }
- }
- /// <summary>
- /// Signals the object that initialization is starting
- /// </summary>
- public void BeginInit()
- {
- this.init = true;
- }
- /// <summary>
- /// Signals the object that initialization is complete
- /// </summary>
- public void EndInit()
- {
- this.init = false;
- this.PerformLayout();
- }
- /// <summary>
- /// Gets whether the Table is currently initializing
- /// </summary>
- [Browsable(false)]
- public bool Initializing
- {
- get
- {
- return this.init;
- }
- }
- #endregion
- #region Mouse
- /// <summary>
- /// This member supports the .NET Framework infrastructure and is not
- /// intended to be used directly from your code
- /// </summary>
- public new void ResetMouseEventArgs()
- {
- if (this.trackMouseEvent == null)
- {
- this.trackMouseEvent = new TRACKMOUSEEVENT();
- this.trackMouseEvent.dwFlags = 3;
- this.trackMouseEvent.hwndTrack = base.Handle;
- }
- this.trackMouseEvent.dwHoverTime = this.HoverTime;
-
- NativeMethods.TrackMouseEvent(this.trackMouseEvent);
- }
- #endregion
- #region Scrolling
- /// <summary>
- /// Updates the scrollbars to reflect any changes made to the Table
- /// </summary>
- public void UpdateScrollBars()
- {
- if (!this.Scrollable || this.ColumnModel == null)
- {
- return;
- }
- // fix: Add width/height check as otherwise minimize
- // causes a crash
- // Portia4ever (kangxj@126.com)
- // 13/09/2005
- // v1.0.1
- if (this.Width == 0 || this.Height == 0)
- {
- return;
- }
- bool hscroll = (this.ColumnModel.VisibleColumnsWidth > this.Width - (this.BorderWidth * 2));
- bool vscroll = this.TotalRowAndHeaderHeight > (this.Height - (this.BorderWidth * 2) - (hscroll ? SystemInformation.HorizontalScrollBarHeight : 0));
- if (vscroll)
- {
- hscroll = (this.ColumnModel.VisibleColumnsWidth > this.Width - (this.BorderWidth * 2) - SystemInformation.VerticalScrollBarWidth);
- }
- if (hscroll)
- {
- Rectangle hscrollBounds = new Rectangle(this.BorderWidth,
- this.Height - this.BorderWidth - SystemInformation.HorizontalScrollBarHeight,
- this.Width - (this.BorderWidth * 2),
- SystemInformation.HorizontalScrollBarHeight);
-
- if (vscroll)
- {
- hscrollBounds.Width -= SystemInformation.VerticalScrollBarWidth;
- }
-
- this.hScrollBar.Visible = true;
- this.hScrollBar.Bounds = hscrollBounds;
- this.hScrollBar.Minimum = 0;
- this.hScrollBar.Maximum = this.ColumnModel.VisibleColumnsWidth;
- this.hScrollBar.SmallChange = Column.MinimumWidth;
- this.hScrollBar.LargeChange = hscrollBounds.Width - 1;
- if (this.hScrollBar.Value > this.hScrollBar.Maximum - this.hScrollBar.LargeChange)
- {
- this.hScrollBar.Value = this.hScrollBar.Maximum - this.hScrollBar.LargeChange;
- }
- }
- else
- {
- this.hScrollBar.Visible = false;
- this.hScrollBar.Value = 0;
- }
- if (vscroll)
- {
- Rectangle vscrollBounds = new Rectangle(this.Width - this.BorderWidth - SystemInformation.VerticalScrollBarWidth,
- this.BorderWidth,
- SystemInformation.VerticalScrollBarWidth,
- this.Height - (this.BorderWidth * 2));
-
- if (hscroll)
- {
- vscrollBounds.Height -= SystemInformation.HorizontalScrollBarHeight;
- }
-
- this.vScrollBar.Visible = true;
- this.vScrollBar.Bounds = vscrollBounds;
- this.vScrollBar.Minimum = 0;
- this.vScrollBar.Maximum = (this.RowCount > this.VisibleRowCount ? this.RowCount - 1 : this.VisibleRowCount);
- this.vScrollBar.SmallChange = 1;
- this.vScrollBar.LargeChange = this.VisibleRowCount - 1;
- if (this.vScrollBar.Value > this.vScrollBar.Maximum - this.vScrollBar.LargeChange)
- {
- this.vScrollBar.Value = this.vScrollBar.Maximum - this.vScrollBar.LargeChange;
- }
- }
- else
- {
- this.vScrollBar.Visible = false;
- this.vScrollBar.Value = 0;
- }
- }
- /// <summary>
- /// Scrolls the contents of the Table horizontally to the specified value
- /// </summary>
- /// <param name="value">The value to scroll to</param>
- protected void HorizontalScroll(int value)
- {
- int scrollVal = this.hScrollBar.Value - value;
- if (scrollVal != 0)
- {
- RECT scrollRect = RECT.FromRectangle(this.PseudoClientRect);
- Rectangle invalidateRect = scrollRect.ToRectangle();
- NativeMethods.ScrollWindow(this.Handle, scrollVal, 0, ref scrollRect, ref scrollRect);
-
- if (scrollVal < 0)
- {
- invalidateRect.X = invalidateRect.Right + scrollVal;
- }
- invalidateRect.Width = Math.Abs(scrollVal);
- this.Invalidate(invalidateRect, false);
- if (this.VScroll)
- {
- this.Invalidate(new Rectangle(this.Width - this.BorderWidth - SystemInformation.VerticalScrollBarWidth,
- this.Height - this.BorderWidth - SystemInformation.HorizontalScrollBarHeight,
- SystemInformation.VerticalScrollBarWidth,
- SystemInformation.HorizontalScrollBarHeight),
- false);
- }
- }
- }
- /// <summary>
- /// Scrolls the contents of the Table vertically to the specified value
- /// </summary>
- /// <param name="value">The value to scroll to</param>
- protected void VerticalScroll(int value)
- {
- int scrollVal = this.vScrollBar.Value - value;
- if (scrollVal != 0)
- {
- RECT scrollRect = RECT.FromRectangle(this.CellDataRect);
- Rectangle invalidateRect = scrollRect.ToRectangle();
- scrollVal *= this.RowHeight;
- NativeMethods.ScrollWindow(this.Handle, 0, scrollVal, ref scrollRect, ref scrollRect);
-
- if (scrollVal < 0)
- {
- invalidateRect.Y = invalidateRect.Bottom + scrollVal;
- }
- invalidateRect.Height = Math.Abs(scrollVal);
- this.Invalidate(invalidateRect, false);
- if (this.HScroll)
- {
- this.Invalidate(new Rectangle(this.Width - this.BorderWidth - SystemInformation.VerticalScrollBarWidth,
- this.Height - this.BorderWidth - SystemInformation.HorizontalScrollBarHeight,
- SystemInformation.VerticalScrollBarWidth,
- SystemInformation.HorizontalScrollBarHeight),
- false);
- }
- }
- }
- /// <summary>
- /// Ensures that the Cell at the specified row and column is visible
- /// within the Table, scrolling the contents of the Table if necessary
- /// </summary>
- /// <param name="row">The zero-based index of the row to scroll into view</param>
- /// <param name="column">The zero-based index of the column to scroll into view</param>
- /// <returns>true if the Table scrolled to the Cell at the specified row
- /// and column, false otherwise</returns>
- public bool EnsureVisible(int row, int column)
- {
- if (!this.Scrollable || (!this.HScroll && !this.VScroll) || row == -1)
- {
- return false;
- }
- if (column == -1)
- {
- if (this.FocusedCell.Column != -1)
- {
- column = this.FocusedCell.Column;
- }
- else
- {
- column = 0;
- }
- }
- int hscrollVal = this.hScrollBar.Value;
- int vscrollVal = this.vScrollBar.Value;
- bool moved = false;
- if (this.HScroll)
- {
- if (column < 0)
- {
- column = 0;
- }
- else if (column >= this.ColumnCount)
- {
- column = this.ColumnCount - 1;
- }
- if (this.ColumnModel.Columns[column].Visible)
- {
- if (this.ColumnModel.Columns[column].Left < this.hScrollBar.Value)
- {
- hscrollVal = this.ColumnModel.Columns[column].Left;
- }
- else if (this.ColumnModel.Columns[column].Right > this.hScrollBar.Value + this.CellDataRect.Width)
- {
- hscrollVal = this.ColumnModel.Columns[column].Right - this.CellDataRect.Width;
- }
- if (hscrollVal > this.hScrollBar.Maximum - this.hScrollBar.LargeChange)
- {
- hscrollVal = this.hScrollBar.Maximum - this.hScrollBar.LargeChange;
- }
- }
- }
- if (this.VScroll)
- {
- if (row < 0)
- {
- vscrollVal = 0;
- }
- else if (row >= this.RowCount)
- {
- vscrollVal = this.RowCount - 1;
- }
- else
- {
- if (row < vscrollVal)
- {
- vscrollVal = row;
- }
- else if (row > vscrollVal + this.vScrollBar.LargeChange)
- {
- vscrollVal += row - (vscrollVal + this.vScrollBar.LargeChange);
- }
- }
- if (vscrollVal > this.vScrollBar.Maximum - this.vScrollBar.LargeChange)
- {
- vscrollVal = (this.vScrollBar.Maximum - this.vScrollBar.LargeChange) + 1;
- }
- }
- if (this.RowRect(row).Bottom > this.CellDataRect.Bottom)
- {
- vscrollVal++;
- }
- moved = (this.hScrollBar.Value != hscrollVal || this.vScrollBar.Value != vscrollVal);
- if (moved)
- {
- this.hScrollBar.Value = hscrollVal;
- this.vScrollBar.Value = vscrollVal;
- this.Invalidate(this.PseudoClientRect);
- }
- return moved;
- }
- /// <summary>
- /// Ensures that the Cell at the specified CellPos is visible within
- /// the Table, scrolling the contents of the Table if necessary
- /// </summary>
- /// <param name="cellPos">A CellPos that contains the zero-based index
- /// of the row and column to scroll into view</param>
- /// <returns></returns>
- public bool EnsureVisible(CellPos cellPos)
- {
- return this.EnsureVisible(cellPos.Row, cellPos.Column);
- }
- /// <summary>
- /// Gets the index of the first visible Column currently displayed in the Table
- /// </summary>
- [Browsable(false)]
- public int FirstVisibleColumn
- {
- get
- {
- if (this.ColumnModel == null || this.ColumnModel.VisibleColumnCount == 0)
- {
- return -1;
- }
- return this.ColumnModel.ColumnIndexAtX(this.hScrollBar.Value);
- }
- }
- /// <summary>
- /// Gets the index of the last visible Column currently displayed in the Table
- /// </summary>
- [Browsable(false)]
- public int LastVisibleColumn
- {
- get
- {
- if (this.ColumnModel == null || this.ColumnModel.VisibleColumnCount == 0)
- {
- return -1;
- }
- int rightEdge = this.hScrollBar.Value + this.PseudoClientRect.Right;
- if (this.VScroll)
- {
- rightEdge -= this.vScrollBar.Width;
- }
-
- int col = this.ColumnModel.ColumnIndexAtX(rightEdge);
- if (col == -1)
- {
- return this.ColumnModel.PreviousVisibleColumn(this.ColumnModel.Columns.Count);
- }
- else if (!this.ColumnModel.Columns[col].Visible)
- {
- return this.ColumnModel.PreviousVisibleColumn(col);
- }
- return col;
- }
- }
- #endregion
- #region Sorting
- /// <summary>
- /// Sorts the last sorted column opposite to its current sort order,
- /// or sorts the currently focused column in ascending order if no
- /// columns have been sorted
- /// </summary>
- public void Sort()
- {
- this.Sort(true);
- }
- /// <summary>
- /// Sorts the last sorted column opposite to its current sort order,
- /// or sorts the currently focused column in ascending order if no
- /// columns have been sorted
- /// </summary>
- /// <param name="stable">Specifies whether a stable sorting method
- /// should be used to sort the column</param>
- public void Sort(bool stable)
- {
- // don't allow sorting if we're being used as a
- // preview table in a ColumnModel editor
- if (this.Preview)
- {
- return;
- }
-
- // if we don't have a sorted column already, check if
- // we can use the column of the cell that has focus
- if (!this.IsValidColumn(this.lastSortedColumn))
- {
- if (this.IsValidColumn(this.focusedCell.Column))
- {
- this.lastSortedColumn = this.focusedCell.Column;
- }
- }
-
- // make sure the last sorted column exists
- if (this.IsValidColumn(this.lastSortedColumn))
- {
- // don't bother if the column won't let us sort
- if (!this.ColumnModel.Columns[this.lastSortedColumn].Sortable)
- {
- return;
- }
-
- // work out which direction we should sort
- SortOrder newOrder = SortOrder.Ascending;
-
- Column column = this.ColumnModel.Columns[this.lastSortedColumn];
-
- if (column.SortOrder == SortOrder.Ascending)
- {
- newOrder = SortOrder.Descending;
- }
- this.Sort(this.lastSortedColumn, column, newOrder, stable);
- }
- }
- /// <summary>
- /// Sorts the specified column opposite to its current sort order,
- /// or in ascending order if the column is not sorted
- /// </summary>
- /// <param name="column">The index of the column to sort</param>
- public void Sort(int column)
- {
- this.Sort(column, true);
- }
- /// <summary>
- /// Sorts the specified column opposite to its current sort order,
- /// or in ascending order if the column is not sorted
- /// </summary>
- /// <param name="column">The index of the column to sort</param>
- /// <param name="stable">Specifies whether a stable sorting method
- /// should be used to sort the column</param>
- public void Sort(int column, bool stable)
- {
- // don't allow sorting if we're being used as a
- // preview table in a ColumnModel editor
- if (this.Preview)
- {
- return;
- }
-
- // make sure the column exists
- if (this.IsValidColumn(column))
- {
- // don't bother if the column won't let us sort
- if (!this.ColumnModel.Columns[column].Sortable)
- {
- return;
- }
-
- // if we already have a different sorted column, set
- // its sort order to none
- if (column != this.lastSortedColumn)
- {
- if (this.IsValidColumn(this.lastSortedColumn))
- {
- this.ColumnModel.Columns[this.lastSortedColumn].InternalSortOrder = SortOrder.None;
- }
- }
-
- this.lastSortedColumn = column;
- // work out which direction we should sort
- SortOrder newOrder = SortOrder.Ascending;
-
- Column col = this.ColumnModel.Columns[column];
-
- if (col.SortOrder == SortOrder.Ascending)
- {
- newOrder = SortOrder.Descending;
- }
- this.Sort(column, col, newOrder, stable);
- }
- }
- /// <summary>
- /// Sorts the specified column in the specified sort direction
- /// </summary>
- /// <param name="column">The index of the column to sort</param>
- /// <param name="sortOrder">The direction the column is to be sorted</param>
- public void Sort(int column, SortOrder sortOrder)
- {
- this.Sort(column, sortOrder, true);
- }
- /// <summary>
- /// Sorts the specified column in the specified sort direction
- /// </summary>
- /// <param name="column">The index of the column to sort</param>
- /// <param name="sortOrder">The direction the column is to be sorted</param>
- /// <param name="stable">Specifies whether a stable sorting method
- /// should be used to sort the column</param>
- public void Sort(int column, SortOrder sortOrder, bool stable)
- {
- // don't allow sorting if we're being used as a
- // preview table in a ColumnModel editor
- if (this.Preview)
- {
- return;
- }
-
- // make sure the column exists
- if (this.IsValidColumn(column))
- {
- // don't bother if the column won't let us sort
- if (!this.ColumnModel.Columns[column].Sortable)
- {
- return;
- }
-
- // if we already have a different sorted column, set
- // its sort order to none
- if (column != this.lastSortedColumn)
- {
- if (this.IsValidColumn(this.lastSortedColumn))
- {
- this.ColumnModel.Columns[this.lastSortedColumn].InternalSortOrder = SortOrder.None;
- }
- }
-
- this.lastSortedColumn = column;
- this.Sort(column, this.ColumnModel.Columns[column], sortOrder, stable);
- }
- }
- /// <summary>
- /// Sorts the specified column in the specified sort direction
- /// </summary>
- /// <param name="index">The index of the column to sort</param>
- /// <param name="column">The column to sort</param>
- /// <param name="sortOrder">The direction the column is to be sorted</param>
- /// <param name="stable">Specifies whether a stable sorting method
- /// should be used to sort the column</param>
- private void Sort(int index, Column column, SortOrder sortOrder, bool stable)
- {
- // make sure a null comparer type doesn't sneak past
-
- ComparerBase comparer = null;
-
- if (column.Comparer != null)
- {
- comparer = (ComparerBase) Activator.CreateInstance(column.Comparer, new object[] {this.TableModel, index, sortOrder});
- }
- else if (column.DefaultComparerType != null)
- {
- comparer = (ComparerBase) Activator.CreateInstance(column.DefaultComparerType, new object[] {this.TableModel, index, sortOrder});
- }
- else
- {
- return;
- }
- column.InternalSortOrder = sortOrder;
- // create the comparer
- SorterBase sorter = null;
- // work out which sort method to use.
- // - InsertionSort/MergeSort are stable sorts,
- // whereas ShellSort/HeapSort are unstable
- // - InsertionSort/ShellSort are faster than
- // MergeSort/HeapSort on small lists and slower
- // on large lists
- // so we choose based on the size of the list and
- // whether the user wants a stable sort
- if (this.TableModel.Rows.Count < 1000)
- {
- if (stable)
- {
- sorter = new InsertionSorter(this.TableModel, index, comparer, sortOrder);
- }
- else
- {
- sorter = new ShellSorter(this.TableModel, index, comparer, sortOrder);
- }
- }
- else
- {
- if (stable)
- {
- sorter = new MergeSorter(this.TableModel, index, comparer, sortOrder);
- }
- else
- {
- sorter = new HeapSorter(this.TableModel, index, comparer, sortOrder);
- }
- }
- // don't let the table redraw
- this.BeginUpdate();
- this.OnBeginSort(new ColumnEventArgs(column, index, ColumnEventType.Sorting, null));
- sorter.Sort();
- this.OnEndSort(new ColumnEventArgs(column, index, ColumnEventType.Sorting, null));
- // redraw any changes
- this.EndUpdate();
- }
- /// <summary>
- /// Returns whether a Column exists at the specified index in the
- /// Table's ColumnModel
- /// </summary>
- /// <param name="column">The index of the column to check</param>
- /// <returns>True if a Column exists at the specified index in the
- /// Table's ColumnModel, false otherwise</returns>
- public bool IsValidColumn(int column)
- {
- if (this.ColumnModel == null)
- {
- return false;
- }
- return (column >= 0 && column < this.ColumnModel.Columns.Count);
- }
- #endregion
- #endregion
- #region Properties
- #region Borders
- /// <summary>
- /// Gets or sets the border style for the Table
- /// </summary>
- [Category("Appearance"),
- DefaultValue(BorderStyle.Fixed3D),
- Description("Indicates the border style for the Table")]
- public BorderStyle BorderStyle
- {
- get
- {
- return this.borderStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(BorderStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(BorderStyle));
- }
-
- if (borderStyle != value)
- {
- this.borderStyle = value;
- this.Invalidate(true);
- }
- }
- }
- /// <summary>
- /// Gets the width of the Tables border
- /// </summary>
- protected int BorderWidth
- {
- get
- {
- if (this.BorderStyle == BorderStyle.Fixed3D)
- {
- return SystemInformation.Border3DSize.Width;
- }
- else if (this.BorderStyle == BorderStyle.FixedSingle)
- {
- return 1;
- }
- return 0;
- }
- }
- #endregion
- #region Cells
- /// <summary>
- /// Gets the last known cell position that the mouse was over
- /// </summary>
- [Browsable(false)]
- public CellPos LastMouseCell
- {
- get
- {
- return this.lastMouseCell;
- }
- }
- /// <summary>
- /// Gets the last known cell position that the mouse's left
- /// button was pressed in
- /// </summary>
- [Browsable(false)]
- public CellPos LastMouseDownCell
- {
- get
- {
- return this.lastMouseDownCell;
- }
- }
- /// <summary>
- /// Gets or sets the position of the Cell that currently has focus
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public CellPos FocusedCell
- {
- get
- {
- return this.focusedCell;
- }
- set
- {
- if (!this.IsValidCell(value))
- {
- return;
- }
- if (!this.TableModel[value].Enabled)
- {
- return;
- }
-
- if (this.focusedCell != value)
- {
- if (!this.focusedCell.IsEmpty)
- {
- this.RaiseCellLostFocus(this.focusedCell);
- }
- this.focusedCell = value;
- if (!value.IsEmpty)
- {
- this.EnsureVisible(value);
- this.RaiseCellGotFocus(value);
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the amount of time (in milliseconds) that that the
- /// mouse pointer must hover over a Cell or Column Header before
- /// a MouseHover event is raised
- /// </summary>
- [Category("Behavior"),
- DefaultValue(1000),
- Description("The amount of time (in milliseconds) that that the mouse pointer must hover over a Cell or Column Header before a MouseHover event is raised")]
- public int HoverTime
- {
- get
- {
- return this.hoverTime;
- }
- set
- {
- if (value < 100)
- {
- throw new ArgumentException("HoverTime cannot be less than 100", "value");
- }
- if (this.hoverTime != value)
- {
- this.hoverTime = value;
- this.ResetMouseEventArgs();
- }
- }
- }
- #endregion
- #region ClientRectangle
- /// <summary>
- /// Gets the rectangle that represents the "client area" of the control.
- /// (The rectangle excludes the borders and scrollbars)
- /// </summary>
- [Browsable(false)]
- public Rectangle PseudoClientRect
- {
- get
- {
- Rectangle clientRect = this.InternalBorderRect;
- if (this.HScroll)
- {
- clientRect.Height -= SystemInformation.HorizontalScrollBarHeight;
- }
- if (this.VScroll)
- {
- clientRect.Width -= SystemInformation.VerticalScrollBarWidth;
- }
- return clientRect;
- }
- }
- /// <summary>
- /// Gets the rectangle that represents the "cell data area" of the control.
- /// (The rectangle excludes the borders, column headers and scrollbars)
- /// </summary>
- [Browsable(false)]
- public Rectangle CellDataRect
- {
- get
- {
- Rectangle clientRect = this.PseudoClientRect;
-
- if (this.HeaderStyle != ColumnHeaderStyle.None && this.ColumnCount > 0)
- {
- clientRect.Y += this.HeaderHeight;
- clientRect.Height -= this.HeaderHeight;
- }
- return clientRect;
- }
- }
- /// <summary>
- ///
- /// </summary>
- private Rectangle InternalBorderRect
- {
- get
- {
- return new Rectangle(this.BorderWidth,
- this.BorderWidth,
- this.Width - (this.BorderWidth * 2),
- this.Height - (this.BorderWidth * 2));
- }
- }
- #endregion
- #region ColumnModel
- /// <summary>
- /// Gets or sets the ColumnModel that contains all the Columns
- /// displayed in the Table
- /// </summary>
- [Category("Columns"),
- DefaultValue(null),
- Description("Specifies the ColumnModel that contains all the Columns displayed in the Table")]
- public ColumnModel ColumnModel
- {
- get
- {
- return this.columnModel;
- }
- set
- {
- if (this.columnModel != value)
- {
- if (this.columnModel != null && this.columnModel.Table == this)
- {
- this.columnModel.InternalTable = null;
- }
- this.columnModel = value;
- if (value != null)
- {
- value.InternalTable = this;
- }
- this.OnColumnModelChanged(EventArgs.Empty);
- }
- }
- }
-
- /// <summary>
- /// Gets or sets whether the Table allows users to resize Column widths
- /// </summary>
- [Category("Columns"),
- DefaultValue(true),
- Description("Specifies whether the Table allows users to resize Column widths")]
- public bool ColumnResizing
- {
- get
- {
- return this.columnResizing;
- }
- set
- {
- if (this.columnResizing != value)
- {
- this.columnResizing = value;
- }
- }
- }
- /// <summary>
- /// Returns the number of Columns in the Table
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int ColumnCount
- {
- get
- {
- if (this.ColumnModel == null)
- {
- return -1;
- }
- return this.ColumnModel.Columns.Count;
- }
- }
- /// <summary>
- /// Returns the index of the currently sorted Column
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int SortingColumn
- {
- get
- {
- return this.lastSortedColumn;
- }
- }
- /// <summary>
- /// Gets or sets the background Color for the currently sorted column
- /// </summary>
- [Category("Columns"),
- Description("The background Color for a sorted Column")]
- public Color SortedColumnBackColor
- {
- get
- {
- return this.sortedColumnBackColor;
- }
- set
- {
- if (this.sortedColumnBackColor != value)
- {
- this.sortedColumnBackColor = value;
- if (this.IsValidColumn(this.lastSortedColumn))
- {
- Rectangle columnRect = this.ColumnRect(this.lastSortedColumn);
- if (this.PseudoClientRect.IntersectsWith(columnRect))
- {
- this.Invalidate(Rectangle.Intersect(this.PseudoClientRect, columnRect));
- }
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's SortedColumnBackColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the SortedColumnBackColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeSortedColumnBackColor()
- {
- return this.sortedColumnBackColor != Color.WhiteSmoke;
- }
- #endregion
- #region DisplayRectangle
- /// <summary>
- /// Gets the rectangle that represents the display area of the Table
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public override Rectangle DisplayRectangle
- {
- get
- {
- Rectangle displayRect = this.CellDataRect;
- if (!this.init)
- {
- displayRect.X -= this.hScrollBar.Value;
- displayRect.Y -= this.vScrollBar.Value;
- }
-
- if (this.ColumnModel == null)
- {
- return displayRect;
- }
-
- if (this.ColumnModel.TotalColumnWidth <= this.CellDataRect.Width)
- {
- displayRect.Width = this.CellDataRect.Width;
- }
- else
- {
- displayRect.Width = this.ColumnModel.VisibleColumnsWidth;
- }
- if (this.TotalRowHeight <= this.CellDataRect.Height)
- {
- displayRect.Height = this.CellDataRect.Height;
- }
- else
- {
- displayRect.Height = this.TotalRowHeight;
- }
- return displayRect;
- }
- }
- #endregion
- #region Editing
- /// <summary>
- /// Gets whether the Table is currently editing a Cell
- /// </summary>
- [Browsable(false)]
- public bool IsEditing
- {
- get
- {
- return !this.EditingCell.IsEmpty;
- }
- }
- /// <summary>
- /// Gets a CellPos that specifies the position of the Cell that
- /// is currently being edited
- /// </summary>
- [Browsable(false)]
- public CellPos EditingCell
- {
- get
- {
- return this.editingCell;
- }
- }
- /// <summary>
- /// Gets the ICellEditor that is currently being used to edit a Cell
- /// </summary>
- [Browsable(false)]
- public ICellEditor EditingCellEditor
- {
- get
- {
- return this.curentCellEditor;
- }
- }
- /// <summary>
- /// Gets or sets the action that causes editing to be initiated
- /// </summary>
- [Category("Editing"),
- DefaultValue(EditStartAction.DoubleClick),
- Description("The action that causes editing to be initiated")]
- public EditStartAction EditStartAction
- {
- get
- {
- return this.editStartAction;
- }
- set
- {
- if (!Enum.IsDefined(typeof(EditStartAction), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(EditStartAction));
- }
-
- if (this.editStartAction != value)
- {
- this.editStartAction = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets the custom key used to initiate Cell editing
- /// </summary>
- [Category("Editing"),
- DefaultValue(Keys.F5),
- Description("The custom key used to initiate Cell editing")]
- public Keys CustomEditKey
- {
- get
- {
- return this.customEditKey;
- }
- set
- {
- if (this.IsReservedKey(value))
- {
- throw new ArgumentException("CustomEditKey cannot be one of the Table's reserved keys " +
- "(Up arrow, Down arrow, Left arrow, Right arrow, PageUp, " +
- "PageDown, Home, End, Tab)", "value");
- }
-
- if (this.customEditKey != value)
- {
- this.customEditKey = value;
- }
- }
- }
- /*/// <summary>
- /// Gets or sets whether pressing the Tab key during editing moves
- /// the editor to the next editable Cell
- /// </summary>
- [Category("Editing"),
- DefaultValue(true),
- Description("")]
- public bool TabMovesEditor
- {
- get
- {
- return this.tabMovesEditor;
- }
- set
- {
- this.tabMovesEditor = value;
- }
- }*/
- #endregion
- #region Grid
- /// <summary>
- /// Gets or sets how grid lines are displayed around rows and columns
- /// </summary>
- [Category("Grid"),
- DefaultValue(GridLines.None),
- Description("Determines how grid lines are displayed around rows and columns")]
- public GridLines GridLines
- {
- get
- {
- return this.gridLines;
- }
- set
- {
- if (!Enum.IsDefined(typeof(GridLines), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(GridLines));
- }
-
- if (this.gridLines != value)
- {
- this.gridLines = value;
- this.Invalidate(this.PseudoClientRect, false);
- }
- }
- }
- /// <summary>
- /// Gets or sets the style of the lines used to draw the grid
- /// </summary>
- [Category("Grid"),
- DefaultValue(GridLineStyle.Solid),
- Description("The style of the lines used to draw the grid")]
- public GridLineStyle GridLineStyle
- {
- get
- {
- return this.gridLineStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(GridLineStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(GridLineStyle));
- }
-
- if (this.gridLineStyle != value)
- {
- this.gridLineStyle = value;
- if (this.GridLines != GridLines.None)
- {
- this.Invalidate(this.PseudoClientRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the Color of the grid lines
- /// </summary>
- [Category("Grid"),
- Description("The color of the grid lines")]
- public Color GridColor
- {
- get
- {
- return this.gridColor;
- }
- set
- {
- if (this.gridColor != value)
- {
- this.gridColor = value;
- if (this.GridLines != GridLines.None)
- {
- this.Invalidate(this.PseudoClientRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's GridColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the GridColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeGridColor()
- {
- return (this.GridColor != SystemColors.Control);
- }
- /// <summary>
- ///
- /// </summary>
- public override Color BackColor
- {
- get
- {
- return base.BackColor;
- }
- set
- {
- base.BackColor = value;
- }
- }
- /// <summary>
- /// Specifies whether the Table's BackColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the BackColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeBackColor()
- {
- return (this.BackColor != Color.White);
- }
- #endregion
- #region Header
- /// <summary>
- /// Gets or sets the column header style
- /// </summary>
- [Category("Columns"),
- DefaultValue(ColumnHeaderStyle.Clickable),
- Description("The style of the column headers")]
- public ColumnHeaderStyle HeaderStyle
- {
- get
- {
- return this.headerStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(ColumnHeaderStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(ColumnHeaderStyle));
- }
-
- if (this.headerStyle != value)
- {
- this.headerStyle = value;
- this.pressedColumn = -1;
- this.hotColumn = -1;
- this.Invalidate();
- }
- }
- }
- /// <summary>
- /// Gets the height of the column headers
- /// </summary>
- [Browsable(false)]
- public int HeaderHeight
- {
- get
- {
- if (this.ColumnModel == null || this.HeaderStyle == ColumnHeaderStyle.None)
- {
- return 0;
- }
- return this.ColumnModel.HeaderHeight;
- }
- }
- /// <summary>
- /// Gets a Rectangle that specifies the size and location of
- /// the Table's column header area
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public Rectangle HeaderRectangle
- {
- get
- {
- return new Rectangle(this.BorderWidth, this.BorderWidth, this.PseudoClientRect.Width, this.HeaderHeight);
- }
- }
- /// <summary>
- /// Gets or sets the font used to draw the text in the column headers
- /// </summary>
- [Category("Columns"),
- Description("The font used to draw the text in the column headers")]
- public Font HeaderFont
- {
- get
- {
- return this.headerFont;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("HeaderFont cannot be null");
- }
- if (this.headerFont != value)
- {
- this.headerFont = value;
- this.HeaderRenderer.Font = value;
- this.Invalidate(this.HeaderRectangle, false);
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's HeaderFont property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the HeaderFont property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeHeaderFont()
- {
- return this.HeaderFont != this.Font;
- }
- /// <summary>
- /// Gets or sets the HeaderRenderer used to draw the Column headers
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public HeaderRenderer HeaderRenderer
- {
- get
- {
- if (this.headerRenderer == null)
- {
- this.headerRenderer = new XPHeaderRenderer();
- }
-
- return this.headerRenderer;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("HeaderRenderer cannot be null");
- }
- if (this.headerRenderer != value)
- {
- this.headerRenderer = value;
- this.headerRenderer.Font = this.HeaderFont;
- this.Invalidate(this.HeaderRectangle, false);
- }
- }
- }
- /// <summary>
- /// Gets the ContextMenu used for Column Headers
- /// </summary>
- [Browsable(false)]
- public HeaderContextMenu HeaderContextMenu
- {
- get
- {
- return this.headerContextMenu;
- }
- }
- /// <summary>
- /// Gets or sets whether the HeaderContextMenu is able to be
- /// displayed when the user right clicks on a Column Header
- /// </summary>
- [Category("Columns"),
- DefaultValue(true),
- Description("Indicates whether the HeaderContextMenu is able to be displayed when the user right clicks on a Column Header")]
- public bool EnableHeaderContextMenu
- {
- get
- {
- return this.HeaderContextMenu.Enabled;
- }
- set
- {
- this.HeaderContextMenu.Enabled = value;
- }
- }
- #endregion
- #region Rows
- /// <summary>
- /// Gets or sets the height of each row
- /// </summary>
- [Browsable(false)]
- public int RowHeight
- {
- get
- {
- if (this.TableModel == null)
- {
- return 0;
- }
- return this.TableModel.RowHeight;
- }
- }
- /// <summary>
- /// Gets the combined height of all the rows in the Table
- /// </summary>
- [Browsable(false)]
- protected int TotalRowHeight
- {
- get
- {
- if (this.TableModel == null)
- {
- return 0;
- }
-
- return this.TableModel.TotalRowHeight;
- }
- }
- /// <summary>
- /// Gets the combined height of all the rows in the Table
- /// plus the height of the column headers
- /// </summary>
- [Browsable(false)]
- protected int TotalRowAndHeaderHeight
- {
- get
- {
- return this.TotalRowHeight + this.HeaderHeight;
- }
- }
- /// <summary>
- /// Returns the number of Rows in the Table
- /// </summary>
- [Browsable(false)]
- public int RowCount
- {
- get
- {
- if (this.TableModel == null)
- {
- return 0;
- }
-
- return this.TableModel.Rows.Count;
- }
- }
- /// <summary>
- /// Gets the number of rows that are visible in the Table
- /// </summary>
- [Browsable(false)]
- public int VisibleRowCount
- {
- get
- {
- int count = this.CellDataRect.Height / this.RowHeight;
- if ((this.CellDataRect.Height % this.RowHeight) > 0)
- {
- count++;
- }
- return count;
- }
- }
- /// <summary>
- /// Gets the index of the first visible row in the Table
- /// </summary>
- [Browsable(false)]
- public int TopIndex
- {
- get
- {
- if (this.TableModel == null || this.TableModel.Rows.Count == 0)
- {
- return -1;
- }
-
- if (this.VScroll)
- {
- return this.vScrollBar.Value;
- }
- return 0;
- }
- }
- /// <summary>
- /// Gets the first visible row in the Table
- /// </summary>
- [Browsable(false)]
- public Row TopItem
- {
- get
- {
- if (this.TableModel == null || this.TableModel.Rows.Count == 0)
- {
- return null;
- }
-
- return this.TableModel.Rows[this.TopIndex];
- }
- }
- /// <summary>
- /// Gets or sets the background color of odd-numbered rows in the Table
- /// </summary>
- [Category("Appearance"),
- DefaultValue(typeof(Color), "Transparent"),
- Description("The background color of odd-numbered rows in the Table")]
- public Color AlternatingRowColor
- {
- get
- {
- return this.alternatingRowColor;
- }
- set
- {
- if (this.alternatingRowColor != value)
- {
- this.alternatingRowColor = value;
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- #endregion
- #region Scrolling
- /// <summary>
- /// Gets or sets a value indicating whether the Table will
- /// allow the user to scroll to any columns or rows placed
- /// outside of its visible boundaries
- /// </summary>
- [Category("Behavior"),
- DefaultValue(true),
- Description("Indicates whether the Table will display scroll bars if it contains more items than can fit in the client area")]
- public bool Scrollable
- {
- get
- {
- return this.scrollable;
- }
- set
- {
- if (this.scrollable != value)
- {
- this.scrollable = value;
- this.PerformLayout();
- }
- }
- }
- /// <summary>
- /// Gets a value indicating whether the horizontal
- /// scroll bar is visible
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public bool HScroll
- {
- get
- {
- if (this.hScrollBar == null)
- {
- return false;
- }
-
- return this.hScrollBar.Visible;
- }
- }
- /// <summary>
- /// Gets a value indicating whether the vertical
- /// scroll bar is visible
- /// </summary>
- [Browsable(false),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public bool VScroll
- {
- get
- {
- if (this.vScrollBar == null)
- {
- return false;
- }
-
- return this.vScrollBar.Visible;
- }
- }
- #endregion
-
- #region Selection
- /// <summary>
- /// Gets or sets whether cells are allowed to be selected
- /// </summary>
- [Category("Selection"),
- DefaultValue(true),
- Description("Specifies whether cells are allowed to be selected")]
- public bool AllowSelection
- {
- get
- {
- return this.allowSelection;
- }
- set
- {
- if (this.allowSelection != value)
- {
- this.allowSelection = value;
- if (!value && this.TableModel != null)
- {
- this.TableModel.Selections.Clear();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets how selected Cells are drawn by a Table
- /// </summary>
- [Category("Selection"),
- DefaultValue(SelectionStyle.ListView),
- Description("Determines how selected Cells are drawn by a Table")]
- public SelectionStyle SelectionStyle
- {
- get
- {
- return this.selectionStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(SelectionStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(SelectionStyle));
- }
- if (this.selectionStyle != value)
- {
- this.selectionStyle = value;
- if (this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets whether multiple cells are allowed to be selected
- /// </summary>
- [Category("Selection"),
- DefaultValue(false),
- Description("Specifies whether multiple cells are allowed to be selected")]
- public bool MultiSelect
- {
- get
- {
- return this.multiSelect;
- }
- set
- {
- if (this.multiSelect != value)
- {
- this.multiSelect = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets whether all other cells in the row are highlighted
- /// when a cell is selected
- /// </summary>
- [Category("Selection"),
- DefaultValue(false),
- Description("Specifies whether all other cells in the row are highlighted when a cell is selected")]
- public bool FullRowSelect
- {
- get
- {
- return this.fullRowSelect;
- }
- set
- {
- if (this.fullRowSelect != value)
- {
- this.fullRowSelect = value;
- if (this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets whether highlighting is removed from the selected
- /// cells when the Table loses focus
- /// </summary>
- [Category("Selection"),
- DefaultValue(false),
- Description("Specifies whether highlighting is removed from the selected cells when the Table loses focus")]
- public bool HideSelection
- {
- get
- {
- return this.hideSelection;
- }
- set
- {
- if (this.hideSelection != value)
- {
- this.hideSelection = value;
- if (!this.Focused && this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the background color of a selected cell
- /// </summary>
- [Category("Selection"),
- Description("The background color of a selected cell")]
- public Color SelectionBackColor
- {
- get
- {
- return this.selectionBackColor;
- }
- set
- {
- if (this.selectionBackColor != value)
- {
- this.selectionBackColor = value;
- if (this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's SelectionBackColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the SelectionBackColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeSelectionBackColor()
- {
- return (this.selectionBackColor != SystemColors.Highlight);
- }
- /// <summary>
- /// Gets or sets the foreground color of a selected cell
- /// </summary>
- [Category("Selection"),
- Description("The foreground color of a selected cell")]
- public Color SelectionForeColor
- {
- get
- {
- return this.selectionForeColor;
- }
- set
- {
- if (this.selectionForeColor != value)
- {
- this.selectionForeColor = value;
- if (this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's SelectionForeColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the SelectionForeColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeSelectionForeColor()
- {
- return (this.selectionForeColor != SystemColors.HighlightText);
- }
- /// <summary>
- /// Gets or sets the background color of a selected cell when the
- /// Table doesn't have the focus
- /// </summary>
- [Category("Selection"),
- Description("The background color of a selected cell when the Table doesn't have the focus")]
- public Color UnfocusedSelectionBackColor
- {
- get
- {
- return this.unfocusedSelectionBackColor;
- }
- set
- {
- if (this.unfocusedSelectionBackColor != value)
- {
- this.unfocusedSelectionBackColor = value;
- if (!this.Focused && !this.HideSelection && this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's UnfocusedSelectionBackColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the UnfocusedSelectionBackColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeUnfocusedSelectionBackColor()
- {
- return (this.unfocusedSelectionBackColor != SystemColors.Control);
- }
- /// <summary>
- /// Gets or sets the foreground color of a selected cell when the
- /// Table doesn't have the focus
- /// </summary>
- [Category("Selection"),
- Description("The foreground color of a selected cell when the Table doesn't have the focus")]
- public Color UnfocusedSelectionForeColor
- {
- get
- {
- return this.unfocusedSelectionForeColor;
- }
- set
- {
- if (this.unfocusedSelectionForeColor != value)
- {
- this.unfocusedSelectionForeColor = value;
- if (!this.Focused && !this.HideSelection && this.TableModel != null)
- {
- //this.Invalidate(Rectangle.Intersect(this.CellDataRect, this.TableModel.Selections.SelectionBounds), false);
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- }
- /// <summary>
- /// Specifies whether the Table's UnfocusedSelectionForeColor property
- /// should be serialized at design time
- /// </summary>
- /// <returns>True if the UnfocusedSelectionForeColor property should be
- /// serialized, False otherwise</returns>
- private bool ShouldSerializeUnfocusedSelectionForeColor()
- {
- return (this.unfocusedSelectionForeColor != SystemColors.ControlText);
- }
- /// <summary>
- /// Gets an array that contains the currently selected Rows
- /// </summary>
- [Browsable(false)]
- public Row[] SelectedItems
- {
- get
- {
- if (this.TableModel == null)
- {
- return new Row[0];
- }
- return this.TableModel.Selections.SelectedItems;
- }
- }
- /// <summary>
- /// Gets an array that contains the indexes of the currently selected Rows
- /// </summary>
- [Browsable(false)]
- public int[] SelectedIndicies
- {
- get
- {
- if (this.TableModel == null)
- {
- return new int[0];
- }
- return this.TableModel.Selections.SelectedIndicies;
- }
- }
- #endregion
- #region TableModel
- /// <summary>
- /// Gets or sets the TableModel that contains all the Rows
- /// and Cells displayed in the Table
- /// </summary>
- [Category("Items"),
- DefaultValue(null),
- Description("Specifies the TableModel that contains all the Rows and Cells displayed in the Table")]
- public TableModel TableModel
- {
- get
- {
- return this.tableModel;
- }
- set
- {
- if (this.tableModel != value)
- {
- if (this.tableModel != null && this.tableModel.Table == this)
- {
- this.tableModel.InternalTable = null;
- }
- this.tableModel = value;
- if (value != null)
- {
- value.InternalTable = this;
- }
- this.OnTableModelChanged(EventArgs.Empty);
- }
- }
- }
- /// <summary>
- /// Gets or sets the text displayed by the Table when it doesn't
- /// contain any items
- /// </summary>
- [Category("Appearance"),
- DefaultValue("There are no items in this view"),
- Description("Specifies the text displayed by the Table when it doesn't contain any items")]
- public string NoItemsText
- {
- get
- {
- return this.noItemsText;
- }
- set
- {
- if (!this.noItemsText.Equals(value))
- {
- this.noItemsText = value;
-
- if (this.ColumnModel == null || this.TableModel == null || this.TableModel.Rows.Count == 0)
- {
- this.Invalidate(this.PseudoClientRect);
- }
- }
- }
- }
- #endregion
- #region TableState
- /// <summary>
- /// Gets or sets the current state of the Table
- /// </summary>
- protected TableState TableState
- {
- get
- {
- return this.tableState;
- }
- set
- {
- this.tableState = value;
- }
- }
- /// <summary>
- /// Calculates the state of the Table at the specified
- /// client coordinates
- /// </summary>
- /// <param name="x">The client x coordinate</param>
- /// <param name="y">The client y coordinate</param>
- protected void CalcTableState(int x, int y)
- {
- TableRegion region = this.HitTest(x, y);
- // are we in the header
- if (region == TableRegion.ColumnHeader)
- {
- int column = this.ColumnIndexAt(x, y);
- // get out of here if we aren't in a column
- if (column == -1)
- {
- this.TableState = TableState.Normal;
- return;
- }
- // get the bounding rectangle for the column's header
- Rectangle columnRect = this.ColumnModel.ColumnHeaderRect(column);
- x = this.ClientToDisplayRect(x, y).X;
- // are we in a resizing section on the left
- if (x < columnRect.Left + Column.ResizePadding)
- {
- this.TableState = TableState.ColumnResizing;
-
- while (column != 0)
- {
- if (this.ColumnModel.Columns[column-1].Visible)
- {
- break;
- }
- column--;
- }
- // if we are in the first visible column or the next column
- // to the left is disabled, then we should be potentialy
- // selecting instead of resizing
- if (column == 0 || !this.ColumnModel.Columns[column-1].Enabled)
- {
- this.TableState = TableState.ColumnSelecting;
- }
- }
- // or a resizing section on the right
- else if (x > columnRect.Right - Column.ResizePadding)
- {
- this.TableState = TableState.ColumnResizing;
- }
- // looks like we're somewhere in the middle of
- // the column header
- else
- {
- this.TableState = TableState.ColumnSelecting;
- }
- }
- else if (region == TableRegion.Cells)
- {
- this.TableState = TableState.Selecting;
- }
- else
- {
- this.TableState = TableState.Normal;
- }
- if (this.TableState == TableState.ColumnResizing && !this.ColumnResizing)
- {
- this.TableState = TableState.ColumnSelecting;
- }
- }
- /// <summary>
- /// Gets whether the Table is able to raise events
- /// </summary>
- protected internal bool CanRaiseEvents
- {
- get
- {
- return (this.IsHandleCreated && this.beginUpdateCount == 0);
- }
- }
- /// <summary>
- /// Gets or sets whether the Table is being used as a preview Table in
- /// a ColumnCollectionEditor
- /// </summary>
- internal bool Preview
- {
- get
- {
- return this.preview;
- }
- set
- {
- this.preview = value;
- }
- }
- #endregion
- #region ToolTips
- /// <summary>
- /// Gets the internal tooltip component
- /// </summary>
- internal ToolTip ToolTip
- {
- get
- {
- return this.toolTip;
- }
- }
- /// <summary>
- /// Gets or sets whether ToolTips are currently enabled for the Table
- /// </summary>
- [Category("ToolTips"),
- DefaultValue(false),
- Description("Specifies whether ToolTips are enabled for the Table.")]
- public bool EnableToolTips
- {
- get
- {
- return this.toolTip.Active;
- }
- set
- {
- this.toolTip.Active = value;
- }
- }
- /// <summary>
- /// Gets or sets the automatic delay for the Table's ToolTip
- /// </summary>
- [Category("ToolTips"),
- DefaultValue(500),
- Description("Specifies the automatic delay for the Table's ToolTip.")]
- public int ToolTipAutomaticDelay
- {
- get
- {
- return this.toolTip.AutomaticDelay;
- }
- set
- {
- if (value > 0 && this.toolTip.AutomaticDelay != value)
- {
- this.toolTip.AutomaticDelay = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets the period of time the Table's ToolTip remains visible if
- /// the mouse pointer is stationary within a Cell with a valid ToolTip text
- /// </summary>
- [Category("ToolTips"),
- DefaultValue(5000),
- Description("Specifies the period of time the Table's ToolTip remains visible if the mouse pointer is stationary within a cell with specified ToolTip text.")]
- public int ToolTipAutoPopDelay
- {
- get
- {
- return this.toolTip.AutoPopDelay;
- }
- set
- {
- if (value > 0 && this.toolTip.AutoPopDelay != value)
- {
- this.toolTip.AutoPopDelay = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets the time that passes before the Table's ToolTip appears
- /// </summary>
- [Category("ToolTips"),
- DefaultValue(1000),
- Description("Specifies the time that passes before the Table's ToolTip appears.")]
- public int ToolTipInitialDelay
- {
- get
- {
- return this.toolTip.InitialDelay;
- }
- set
- {
- if (value > 0 && this.toolTip.InitialDelay != value)
- {
- this.toolTip.InitialDelay = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets whether the Table's ToolTip window is
- /// displayed even when its parent control is not active
- /// </summary>
- [Category("ToolTips"),
- DefaultValue(false),
- Description("Specifies whether the Table's ToolTip window is displayed even when its parent control is not active.")]
- public bool ToolTipShowAlways
- {
- get
- {
- return this.toolTip.ShowAlways;
- }
- set
- {
- if (this.toolTip.ShowAlways != value)
- {
- this.toolTip.ShowAlways = value;
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- private void ResetToolTip()
- {
- bool tooltipActive = this.ToolTip.Active;
- if (tooltipActive)
- {
- this.ToolTip.Active = false;
- }
- this.ResetMouseEventArgs();
- this.ToolTip.SetToolTip(this, null);
- if (tooltipActive)
- {
- this.ToolTip.Active = true;
- }
- }
- #endregion
- #endregion
- #region Events
- #region Cells
- /// <summary>
- /// Raises the CellPropertyChanged event
- /// </summary>
- /// <param name="e">A CellEventArgs that contains the event data</param>
- protected internal virtual void OnCellPropertyChanged(CellEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.InvalidateCell(e.Row, e.Column);
- if (CellPropertyChanged != null)
- {
- CellPropertyChanged(this, e);
- }
- if (e.EventType == CellEventType.CheckStateChanged)
- {
- this.OnCellCheckChanged(new CellCheckBoxEventArgs(e.Cell, e.Column, e.Row));
- }
- }
- }
- /// <summary>
- /// Handler for a Cells PropertyChanged event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">A CellEventArgs that contains the event data</param>
- private void cell_PropertyChanged(object sender, CellEventArgs e)
- {
- this.OnCellPropertyChanged(e);
- }
- #region Buttons
- /// <summary>
- /// Raises the CellButtonClicked event
- /// </summary>
- /// <param name="e">A CellButtonEventArgs that contains the event data</param>
- protected internal virtual void OnCellButtonClicked(CellButtonEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (CellButtonClicked != null)
- {
- CellButtonClicked(this, e);
- }
- }
- }
- #endregion
- #region CheckBox
- /// <summary>
- /// Raises the CellCheckChanged event
- /// </summary>
- /// <param name="e">A CellCheckChanged that contains the event data</param>
- protected internal virtual void OnCellCheckChanged(CellCheckBoxEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (CellCheckChanged != null)
- {
- CellCheckChanged(this, e);
- }
- }
- }
- #endregion
- #region Focus
- /// <summary>
- /// Raises the CellGotFocus event
- /// </summary>
- /// <param name="e">A CellFocusEventArgs that contains the event data</param>
- protected virtual void OnCellGotFocus(CellFocusEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnGotFocus(e);
- }
-
- if (CellGotFocus != null)
- {
- CellGotFocus(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the GotFocus event for the Cell at the specified position
- /// </summary>
- /// <param name="cellPos">The position of the Cell that gained focus</param>
- protected void RaiseCellGotFocus(CellPos cellPos)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
-
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(cellPos.Column);
- if (renderer != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellFocusEventArgs cfea = new CellFocusEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column));
- this.OnCellGotFocus(cfea);
- }
- }
- /// <summary>
- /// Raises the CellLostFocus event
- /// </summary>
- /// <param name="e">A CellFocusEventArgs that contains the event data</param>
- protected virtual void OnCellLostFocus(CellFocusEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnLostFocus(e);
- }
-
- if (CellLostFocus != null)
- {
- CellLostFocus(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the LostFocus event for the Cell at the specified position
- /// </summary>
- /// <param name="cellPos">The position of the Cell that lost focus</param>
- protected void RaiseCellLostFocus(CellPos cellPos)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
-
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(cellPos.Column);
- if (renderer != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel[cellPos.Row, cellPos.Column];
- }
- CellFocusEventArgs cfea = new CellFocusEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column));
- this.OnCellLostFocus(cfea);
- }
- }
- #endregion
- #region Keys
- /// <summary>
- /// Raises the CellKeyDown event
- /// </summary>
- /// <param name="e">A CellKeyEventArgs that contains the event data</param>
- protected virtual void OnCellKeyDown(CellKeyEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnKeyDown(e);
- }
-
- if (CellKeyDown != null)
- {
- CellKeyDown(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a KeyDown event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- /// <param name="e">A KeyEventArgs that contains the event data</param>
- protected void RaiseCellKeyDown(CellPos cellPos, KeyEventArgs e)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (!this.TableModel[cellPos].Enabled)
- {
- return;
- }
-
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellKeyEventArgs ckea = new CellKeyEventArgs(cell, this, cellPos, this.CellRect(cellPos.Row, cellPos.Column), e);
- this.OnCellKeyDown(ckea);
- }
- }
-
- /// <summary>
- /// Raises the CellKeyUp event
- /// </summary>
- /// <param name="e">A CellKeyEventArgs that contains the event data</param>
- protected virtual void OnCellKeyUp(CellKeyEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnKeyUp(e);
- }
-
- if (CellKeyUp != null)
- {
- CellKeyUp(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a KeyUp event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- /// <param name="e">A KeyEventArgs that contains the event data</param>
- protected void RaiseCellKeyUp(CellPos cellPos, KeyEventArgs e)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (!this.TableModel[cellPos].Enabled)
- {
- return;
- }
-
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellKeyEventArgs ckea = new CellKeyEventArgs(cell, this, cellPos, this.CellRect(cellPos.Row, cellPos.Column), e);
- this.OnCellKeyUp(ckea);
- }
- }
- #endregion
- #region Mouse
- #region MouseEnter
- /// <summary>
- /// Raises the CellMouseEnter event
- /// </summary>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- protected virtual void OnCellMouseEnter(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnMouseEnter(e);
- }
-
- if (CellMouseEnter != null)
- {
- CellMouseEnter(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseEnter event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- protected void RaiseCellMouseEnter(CellPos cellPos)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellMouseEventArgs mcea = new CellMouseEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column));
- this.OnCellMouseEnter(mcea);
- }
- }
- #endregion
- #region MouseLeave
- /// <summary>
- /// Raises the CellMouseLeave event
- /// </summary>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- protected virtual void OnCellMouseLeave(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnMouseLeave(e);
- }
-
- if (CellMouseLeave != null)
- {
- CellMouseLeave(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseLeave event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- protected internal void RaiseCellMouseLeave(CellPos cellPos)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellMouseEventArgs mcea = new CellMouseEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column));
- this.OnCellMouseLeave(mcea);
- }
- }
- #endregion
- #region MouseUp
- /// <summary>
- /// Raises the CellMouseUp event
- /// </summary>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- protected virtual void OnCellMouseUp(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnMouseUp(e);
- }
-
- if (CellMouseUp != null)
- {
- CellMouseUp(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseUp event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected void RaiseCellMouseUp(CellPos cellPos, MouseEventArgs e)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (!this.TableModel[cellPos].Enabled)
- {
- return;
- }
-
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellMouseEventArgs mcea = new CellMouseEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column), e);
- this.OnCellMouseUp(mcea);
- }
- }
- #endregion
- #region MouseDown
- /// <summary>
- /// Raises the CellMouseDown event
- /// </summary>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- protected virtual void OnCellMouseDown(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnMouseDown(e);
- }
-
- if (CellMouseDown != null)
- {
- CellMouseDown(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseDown event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected void RaiseCellMouseDown(CellPos cellPos, MouseEventArgs e)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (!this.TableModel[cellPos].Enabled)
- {
- return;
- }
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellMouseEventArgs mcea = new CellMouseEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column), e);
- this.OnCellMouseDown(mcea);
- }
- }
- #endregion
- #region MouseMove
- /// <summary>
- /// Raises the CellMouseMove event
- /// </summary>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- protected virtual void OnCellMouseMove(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(e.Column);
- if (renderer != null)
- {
- renderer.OnMouseMove(e);
- }
-
- if (CellMouseMove != null)
- {
- CellMouseMove(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseMove event for the Cell at the specified cell position
- /// </summary>
- /// <param name="cellPos">The position of the Cell</param>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected void RaiseCellMouseMove(CellPos cellPos, MouseEventArgs e)
- {
- if (!this.IsValidCell(cellPos))
- {
- return;
- }
- if (this.ColumnModel.GetCellRenderer(cellPos.Column) != null)
- {
- Cell cell = null;
- if (cellPos.Column < this.TableModel.Rows[cellPos.Row].Cells.Count)
- {
- cell = this.TableModel.Rows[cellPos.Row].Cells[cellPos.Column];
- }
- CellMouseEventArgs mcea = new CellMouseEventArgs(cell, this, cellPos.Row, cellPos.Column, this.CellRect(cellPos.Row, cellPos.Column), e);
- this.OnCellMouseMove(mcea);
- }
- }
- /// <summary>
- /// Resets the last known cell position that the mouse was over to empty
- /// </summary>
- internal void ResetLastMouseCell()
- {
- if (!this.lastMouseCell.IsEmpty)
- {
- this.ResetMouseEventArgs();
- CellPos oldLastMouseCell = this.lastMouseCell;
- this.lastMouseCell = CellPos.Empty;
-
- this.RaiseCellMouseLeave(oldLastMouseCell);
- }
- }
- #endregion
- #region MouseHover
- /// <summary>
- /// Raises the CellHover event
- /// </summary>
- /// <param name="e">A CellEventArgs that contains the event data</param>
- protected virtual void OnCellMouseHover(CellMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (CellMouseHover != null)
- {
- CellMouseHover(e.Cell, e);
- }
- }
- }
- #endregion
- #region Click
-
- /// <summary>
- /// Raises the CellClick event
- /// </summary>
- /// <param name="e">A CellEventArgs that contains the event data</param>
- protected virtual void OnCellClick(CellMouseEventArgs e)
- {
- if (!this.IsCellEnabled(e.CellPos))
- {
- return;
- }
-
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(this.LastMouseCell.Column);
- if (renderer != null)
- {
- renderer.OnClick(e);
- }
-
- if (CellClick != null)
- {
- CellClick(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises the CellDoubleClick event
- /// </summary>
- /// <param name="e">A CellEventArgs that contains the event data</param>
- protected virtual void OnCellDoubleClick(CellMouseEventArgs e)
- {
- if (!this.IsCellEnabled(e.CellPos))
- {
- return;
- }
-
- if (this.CanRaiseEvents)
- {
- ICellRenderer renderer = this.ColumnModel.GetCellRenderer(this.LastMouseCell.Column);
- if (renderer != null)
- {
- renderer.OnDoubleClick(e);
- }
-
- if (CellDoubleClick != null)
- {
- CellDoubleClick(e.Cell, e);
- }
- }
- }
- #endregion
- #endregion
- #endregion
- #region Columns
- /// <summary>
- /// Raises the ColumnPropertyChanged event
- /// </summary>
- /// <param name="e">A ColumnEventArgs that contains the event data</param>
- protected internal virtual void OnColumnPropertyChanged(ColumnEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- Rectangle columnHeaderRect;
-
- if (e.Index != -1)
- {
- columnHeaderRect = this.ColumnHeaderRect(e.Index);
- }
- else
- {
- columnHeaderRect = this.ColumnHeaderRect(e.Column);
- }
-
- switch (e.EventType)
- {
- case ColumnEventType.VisibleChanged:
- case ColumnEventType.WidthChanged:
- {
- if (e.EventType == ColumnEventType.VisibleChanged)
- {
- if (e.Column.Visible && e.Index != this.lastSortedColumn)
- {
- e.Column.InternalSortOrder = SortOrder.None;
- }
- if (e.Index == this.FocusedCell.Column && !e.Column.Visible)
- {
- int index = this.ColumnModel.NextVisibleColumn(e.Index);
- if (index == -1)
- {
- index = this.ColumnModel.PreviousVisibleColumn(e.Index);
- }
- if (index != -1)
- {
- this.FocusedCell = new CellPos(this.FocusedCell.Row, index);
- }
- else
- {
- this.FocusedCell = CellPos.Empty;
- }
- }
- }
- if (columnHeaderRect.X <= 0)
- {
- this.Invalidate(this.PseudoClientRect);
- }
- else if (columnHeaderRect.Left <= this.PseudoClientRect.Right)
- {
- this.Invalidate(new Rectangle(columnHeaderRect.X,
- this.PseudoClientRect.Top,
- this.PseudoClientRect.Right-columnHeaderRect.X,
- this.PseudoClientRect.Height));
- }
- this.UpdateScrollBars();
-
- break;
- }
- case ColumnEventType.TextChanged:
- case ColumnEventType.StateChanged:
- case ColumnEventType.ImageChanged:
- case ColumnEventType.HeaderAlignmentChanged:
- {
- if (columnHeaderRect.IntersectsWith(this.HeaderRectangle))
- {
- this.Invalidate(columnHeaderRect);
- }
-
- break;
- }
- case ColumnEventType.AlignmentChanged:
- case ColumnEventType.RendererChanged:
- case ColumnEventType.EnabledChanged:
- {
- if (e.EventType == ColumnEventType.EnabledChanged)
- {
- if (e.Index == this.FocusedCell.Column)
- {
- this.FocusedCell = CellPos.Empty;
- }
- }
-
- if (columnHeaderRect.IntersectsWith(this.HeaderRectangle))
- {
- this.Invalidate(new Rectangle(columnHeaderRect.X,
- this.PseudoClientRect.Top,
- columnHeaderRect.Width,
- this.PseudoClientRect.Height));
- }
-
- break;
- }
- }
- if (ColumnPropertyChanged != null)
- {
- ColumnPropertyChanged(e.Column, e);
- }
- }
- }
- #endregion
- #region Column Headers
-
- #region MouseEnter
- /// <summary>
- /// Raises the HeaderMouseEnter event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseEnter(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnMouseEnter(e);
- }
-
- if (HeaderMouseEnter != null)
- {
- HeaderMouseEnter(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseEnter event for the Column header at the specified colunm
- /// index position
- /// </summary>
- /// <param name="index">The index of the column to recieve the event</param>
- protected void RaiseHeaderMouseEnter(int index)
- {
- if (index < 0 || this.ColumnModel == null || index >= this.ColumnModel.Columns.Count)
- {
- return;
- }
- if (this.HeaderRenderer != null)
- {
- Column column = this.ColumnModel.Columns[index];
- HeaderMouseEventArgs mhea = new HeaderMouseEventArgs(column, this, index, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(index)));
- this.OnHeaderMouseEnter(mhea);
- }
- }
- #endregion
- #region MouseLeave
- /// <summary>
- /// Raises the HeaderMouseLeave event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseLeave(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnMouseLeave(e);
- }
- if (HeaderMouseLeave != null)
- {
- HeaderMouseLeave(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseLeave event for the Column header at the specified colunm
- /// index position
- /// </summary>
- /// <param name="index">The index of the column to recieve the event</param>
- protected void RaiseHeaderMouseLeave(int index)
- {
- if (index < 0 || this.ColumnModel == null || index >= this.ColumnModel.Columns.Count)
- {
- return;
- }
- if (this.HeaderRenderer != null)
- {
- Column column = this.ColumnModel.Columns[index];
- HeaderMouseEventArgs mhea = new HeaderMouseEventArgs(column, this, index, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(index)));
- this.OnHeaderMouseLeave(mhea);
- }
- }
- #endregion
- #region MouseUp
- /// <summary>
- /// Raises the HeaderMouseUp event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseUp(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnMouseUp(e);
- }
- if (HeaderMouseUp != null)
- {
- HeaderMouseUp(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseUp event for the Column header at the specified colunm
- /// index position
- /// </summary>
- /// <param name="index">The index of the column to recieve the event</param>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected void RaiseHeaderMouseUp(int index, MouseEventArgs e)
- {
- if (index < 0 || this.ColumnModel == null || index >= this.ColumnModel.Columns.Count)
- {
- return;
- }
- if (this.HeaderRenderer != null)
- {
- Column column = this.ColumnModel.Columns[index];
- HeaderMouseEventArgs mhea = new HeaderMouseEventArgs(column, this, index, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(index)), e);
- this.OnHeaderMouseUp(mhea);
- }
- }
- #endregion
- #region MouseDown
- /// <summary>
- /// Raises the HeaderMouseDown event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseDown(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnMouseDown(e);
- }
-
- if (HeaderMouseDown != null)
- {
- HeaderMouseDown(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseDown event for the Column header at the specified colunm
- /// index position
- /// </summary>
- /// <param name="index">The index of the column to recieve the event</param>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected void RaiseHeaderMouseDown(int index, MouseEventArgs e)
- {
- if (index < 0 || this.ColumnModel == null || index >= this.ColumnModel.Columns.Count)
- {
- return;
- }
- if (this.HeaderRenderer != null)
- {
- Column column = this.ColumnModel.Columns[index];
- HeaderMouseEventArgs mhea = new HeaderMouseEventArgs(column, this, index, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(index)), e);
- this.OnHeaderMouseDown(mhea);
- }
- }
- #endregion
- #region MouseMove
- /// <summary>
- /// Raises the HeaderMouseMove event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseMove(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnMouseMove(e);
- }
-
- if (HeaderMouseMove != null)
- {
- HeaderMouseMove(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises a MouseMove event for the Column header at the specified colunm
- /// index position
- /// </summary>
- /// <param name="index">The index of the column to recieve the event</param>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected void RaiseHeaderMouseMove(int index, MouseEventArgs e)
- {
- if (index < 0 || this.ColumnModel == null || index >= this.ColumnModel.Columns.Count)
- {
- return;
- }
- if (this.HeaderRenderer != null)
- {
- Column column = this.ColumnModel.Columns[index];
- HeaderMouseEventArgs mhea = new HeaderMouseEventArgs(column, this, index, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(index)), e);
- this.OnHeaderMouseMove(mhea);
- }
- }
- /// <summary>
- /// Resets the current "hot" column
- /// </summary>
- internal void ResetHotColumn()
- {
- if (this.hotColumn != -1)
- {
- this.ResetMouseEventArgs();
- int oldHotColumn = this.hotColumn;
- this.hotColumn = -1;
-
- this.RaiseHeaderMouseLeave(oldHotColumn);
- }
- }
- #endregion
- #region MouseHover
- /// <summary>
- /// Raises the HeaderMouseHover event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderMouseHover(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (HeaderMouseHover != null)
- {
- HeaderMouseHover(e.Column, e);
- }
- }
- }
- #endregion
- #region Click
-
- /// <summary>
- /// Raises the HeaderClick event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderClick(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnClick(e);
- }
-
- if (HeaderClick != null)
- {
- HeaderClick(e.Column, e);
- }
- }
- }
- /// <summary>
- /// Raises the HeaderDoubleClick event
- /// </summary>
- /// <param name="e">A HeaderMouseEventArgs that contains the event data</param>
- protected virtual void OnHeaderDoubleClick(HeaderMouseEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (this.HeaderRenderer != null)
- {
- this.HeaderRenderer.OnDoubleClick(e);
- }
-
- if (HeaderDoubleClick != null)
- {
- HeaderDoubleClick(e.Column, e);
- }
- }
- }
- #endregion
- #endregion
- #region ColumnModel
- /// <summary>
- /// Raises the ColumnModelChanged event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected virtual void OnColumnModelChanged(EventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (ColumnModelChanged != null)
- {
- ColumnModelChanged(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the ColumnAdded event
- /// </summary>
- /// <param name="e">A ColumnModelEventArgs that contains the event data</param>
- protected internal virtual void OnColumnAdded(ColumnModelEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (ColumnAdded != null)
- {
- ColumnAdded(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the ColumnRemoved event
- /// </summary>
- /// <param name="e">A ColumnModelEventArgs that contains the event data</param>
- protected internal virtual void OnColumnRemoved(ColumnModelEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (ColumnRemoved != null)
- {
- ColumnRemoved(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the HeaderHeightChanged event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected internal virtual void OnHeaderHeightChanged(EventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (HeaderHeightChanged != null)
- {
- HeaderHeightChanged(this, e);
- }
- }
- }
- #endregion
- #region Editing
- /// <summary>
- /// Raises the BeginEditing event
- /// </summary>
- /// <param name="e">A CellEditEventArgs that contains the event data</param>
- protected internal virtual void OnBeginEditing(CellEditEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (BeginEditing != null)
- {
- BeginEditing(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises the EditingStopped event
- /// </summary>
- /// <param name="e">A CellEditEventArgs that contains the event data</param>
- protected internal virtual void OnEditingStopped(CellEditEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (EditingStopped != null)
- {
- EditingStopped(e.Cell, e);
- }
- }
- }
- /// <summary>
- /// Raises the EditingCancelled event
- /// </summary>
- /// <param name="e">A CellEditEventArgs that contains the event data</param>
- protected internal virtual void OnEditingCancelled(CellEditEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (EditingCancelled != null)
- {
- EditingCancelled(e.Cell, e);
- }
- }
- }
- #endregion
- #region Focus
- /// <summary>
- /// Raises the GotFocus event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnGotFocus(EventArgs e)
- {
- if (this.FocusedCell.IsEmpty)
- {
- CellPos p = this.FindNextVisibleEnabledCell(this.FocusedCell, true, true, true, true);
-
- if (this.IsValidCell(p))
- {
- this.FocusedCell = p;
- }
- }
- else
- {
- this.RaiseCellGotFocus(this.FocusedCell);
- }
- if (this.SelectedIndicies.Length > 0)
- {
- this.Invalidate(this.CellDataRect);
- }
- base.OnGotFocus(e);
- }
- /// <summary>
- /// Raises the LostFocus event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnLostFocus(EventArgs e)
- {
- if (!this.FocusedCell.IsEmpty)
- {
- this.RaiseCellLostFocus(this.FocusedCell);
- }
- if (this.SelectedIndicies.Length > 0)
- {
- this.Invalidate(this.CellDataRect);
- }
-
- base.OnLostFocus(e);
- }
- #endregion
- #region Keys
- #region KeyDown
- /// <summary>
- /// Raises the KeyDown event
- /// </summary>
- /// <param name="e">A KeyEventArgs that contains the event data</param>
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (this.IsValidCell(this.FocusedCell))
- {
- if (this.IsReservedKey(e.KeyData))
- {
- Keys key = e.KeyData & Keys.KeyCode;
- if (key == Keys.Up || key == Keys.Down || key == Keys.Left || key == Keys.Right)
- {
- CellPos nextCell;
- if (key == Keys.Up)
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, this.FocusedCell.Row > 0, false, false, false);
- }
- else if (key == Keys.Down)
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, this.FocusedCell.Row < this.RowCount - 1, true, false, false);
- }
- else if (key == Keys.Left)
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, false, false, false, true);
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, false, true, false, true);
- }
- if (nextCell != CellPos.Empty)
- {
- this.FocusedCell = nextCell;
-
- if ((e.KeyData & Keys.Modifiers) == Keys.Shift && this.MultiSelect)
- {
- this.TableModel.Selections.AddShiftSelectedCell(this.FocusedCell);
- }
- else
- {
- this.TableModel.Selections.SelectCell(this.FocusedCell);
- }
- }
- }
- else if (e.KeyData == Keys.PageUp)
- {
- if (this.RowCount > 0)
- {
- CellPos nextCell;
-
- if (!this.VScroll)
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(0, this.FocusedCell.Column), true, true, true, false);
- }
- else
- {
- if (this.FocusedCell.Row > this.vScrollBar.Value && this.TableModel[this.vScrollBar.Value, this.FocusedCell.Column].Enabled)
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(this.vScrollBar.Value, this.FocusedCell.Column), true, true, true, false);
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(Math.Max(-1, this.vScrollBar.Value - (this.vScrollBar.LargeChange - 1)), this.FocusedCell.Column), true, true, true, false);
- }
- }
- if (nextCell != CellPos.Empty)
- {
- this.FocusedCell = nextCell;
-
- this.TableModel.Selections.SelectCell(this.FocusedCell);
- }
- }
- }
- else if (e.KeyData == Keys.PageDown)
- {
- if (this.RowCount > 0)
- {
- CellPos nextCell;
-
- if (!this.VScroll)
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(this.RowCount - 1, this.FocusedCell.Column), true, false, true, false);
- }
- else
- {
- if (this.FocusedCell.Row < this.vScrollBar.Value + this.vScrollBar.LargeChange)
- {
- if (this.FocusedCell.Row == (this.vScrollBar.Value + this.vScrollBar.LargeChange) - 1 &&
- this.RowRect(this.vScrollBar.Value + this.vScrollBar.LargeChange).Bottom > this.CellDataRect.Bottom)
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(Math.Min(this.RowCount - 1, this.FocusedCell.Row - 1 + this.vScrollBar.LargeChange), this.FocusedCell.Column), true, false, true, false);
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(this.vScrollBar.Value + this.vScrollBar.LargeChange - 1, this.FocusedCell.Column), true, false, true, false);
- }
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(Math.Min(this.RowCount - 1, this.FocusedCell.Row + this.vScrollBar.LargeChange), this.FocusedCell.Column), true, false, true, false);
- }
- }
- if (nextCell != CellPos.Empty)
- {
- this.FocusedCell = nextCell;
-
- this.TableModel.Selections.SelectCell(this.FocusedCell);
- }
- }
- }
- else if (e.KeyData == Keys.Home || e.KeyData == Keys.End)
- {
- if (this.RowCount > 0)
- {
- CellPos nextCell;
-
- if (e.KeyData == Keys.Home)
- {
- nextCell = this.FindNextVisibleEnabledCell(CellPos.Empty, true, true, true, true);
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(new CellPos(this.RowCount-1, this.TableModel.Rows[this.RowCount-1].Cells.Count), true, false, true, true);
- }
- if (nextCell != CellPos.Empty)
- {
- this.FocusedCell = nextCell;
-
- this.TableModel.Selections.SelectCell(this.FocusedCell);
- }
- }
- }
- }
- else
- {
- // check if we can start editing with the custom edit key
- if (e.KeyData == this.CustomEditKey && this.EditStartAction == EditStartAction.CustomKey)
- {
- this.EditCell(this.FocusedCell);
- return;
- }
-
- // send all other key events to the cell's renderer
- // for further processing
- this.RaiseCellKeyDown(this.FocusedCell, e);
- }
- }
- else
- {
- if (this.FocusedCell == CellPos.Empty)
- {
- Keys key = e.KeyData & Keys.KeyCode;
-
- if (this.IsReservedKey(e.KeyData))
- {
- if (key == Keys.Down || key == Keys.Right)
- {
- CellPos nextCell;
- if (key == Keys.Down)
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, true, true, true, false);
- }
- else
- {
- nextCell = this.FindNextVisibleEnabledCell(this.FocusedCell, false, true, true, true);
- }
- if (nextCell != CellPos.Empty)
- {
- this.FocusedCell = nextCell;
-
- if ((e.KeyData & Keys.Modifiers) == Keys.Shift && this.MultiSelect)
- {
- this.TableModel.Selections.AddShiftSelectedCell(this.FocusedCell);
- }
- else
- {
- this.TableModel.Selections.SelectCell(this.FocusedCell);
- }
- }
- }
- }
- }
- }
- }
- #endregion
- #region KeyUp
- /// <summary>
- /// Raises the KeyUp event
- /// </summary>
- /// <param name="e">A KeyEventArgs that contains the event data</param>
- protected override void OnKeyUp(KeyEventArgs e)
- {
- base.OnKeyUp(e);
- if (!this.IsReservedKey(e.KeyData))
- {
- //
- if (e.KeyData == this.CustomEditKey && this.EditStartAction == EditStartAction.CustomKey)
- {
- return;
- }
-
- // send all other key events to the cell's renderer
- // for further processing
- this.RaiseCellKeyUp(this.FocusedCell, e);
- }
- }
- #endregion
- #endregion
- #region Layout
- /// <summary>
- /// Raises the Layout event
- /// </summary>
- /// <param name="levent">A LayoutEventArgs that contains the event data</param>
- protected override void OnLayout(LayoutEventArgs levent)
- {
- if (!this.IsHandleCreated || this.init)
- {
- return;
- }
-
- base.OnLayout(levent);
- this.UpdateScrollBars();
- }
- #endregion
- #region Mouse
- #region MouseUp
- /// <summary>
- /// Raises the MouseUp event
- /// </summary>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected override void OnMouseUp(MouseEventArgs e)
- {
- base.OnMouseUp(e);
- if (!this.CanRaiseEvents)
- {
- return;
- }
- // work out the current state of play
- this.CalcTableState(e.X, e.Y);
-
- TableRegion region = this.HitTest(e.X, e.Y);
- if (e.Button == MouseButtons.Left)
- {
- // if the left mouse button was down for a cell,
- // Raise a mouse up for that cell
- if (!this.LastMouseDownCell.IsEmpty)
- {
- if (this.IsValidCell(this.LastMouseDownCell))
- {
- this.RaiseCellMouseUp(this.LastMouseDownCell, e);
- }
- // reset the lastMouseDownCell
- this.lastMouseDownCell = CellPos.Empty;
- }
- // if we have just finished resizing, it might
- // be a good idea to relayout the table
- if (this.resizingColumnIndex != -1)
- {
- if (this.resizingColumnWidth != -1)
- {
- this.DrawReversibleLine(this.ColumnRect(this.resizingColumnIndex).Left + this.resizingColumnWidth);
- }
-
- this.ColumnModel.Columns[this.resizingColumnIndex].Width = this.resizingColumnWidth;
-
- this.resizingColumnIndex = -1;
- this.resizingColumnWidth = -1;
- this.UpdateScrollBars();
- this.Invalidate(this.PseudoClientRect, true);
- }
- // check if the mouse was released in a column header
- if (region == TableRegion.ColumnHeader)
- {
- int column = this.ColumnIndexAt(e.X, e.Y);
- // if we are in the header, check if we are in the pressed column
- if (this.pressedColumn != -1)
- {
- if (this.pressedColumn == column)
- {
- if (this.hotColumn != -1 && this.hotColumn != column)
- {
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Normal;
- }
-
- this.ColumnModel.Columns[this.pressedColumn].InternalColumnState = ColumnState.Hot;
- this.RaiseHeaderMouseUp(column, e);
- }
- this.pressedColumn = -1;
- // only sort the column if we have rows to sort
- if (this.ColumnModel.Columns[column].Sortable)
- {
- if (this.TableModel != null && this.TableModel.Rows.Count > 0)
- {
- this.Sort(column);
- }
- }
- this.Invalidate(this.HeaderRectangle, false);
- }
- return;
- }
- // the mouse wasn't released in a column header, so if we
- // have a pressed column then we need to make it unpressed
- if (this.pressedColumn != -1)
- {
- this.pressedColumn = -1;
- this.Invalidate(this.HeaderRectangle, false);
- }
- }
- }
- #endregion
- #region MouseDown
- /// <summary>
- /// Raises the MouseDown event
- /// </summary>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected override void OnMouseDown(MouseEventArgs e)
- {
- base.OnMouseDown(e);
- if (!this.CanRaiseEvents)
- {
- return;
- }
- this.CalcTableState(e.X, e.Y);
- TableRegion region = this.HitTest(e.X, e.Y);
- int row = this.RowIndexAt(e.X, e.Y);
- int column = this.ColumnIndexAt(e.X, e.Y);
-
- if (this.IsEditing)
- {
- if (this.EditingCell.Row != row || this.EditingCell.Column != column)
- {
- this.Focus();
- if (region == TableRegion.ColumnHeader && e.Button != MouseButtons.Right)
- {
- return;
- }
- }
- }
- #region ColumnHeader
- if (region == TableRegion.ColumnHeader)
- {
- if (e.Button == MouseButtons.Right && this.HeaderContextMenu.Enabled)
- {
- this.HeaderContextMenu.Show(this, new Point(e.X, e.Y));
-
- return;
- }
- if (column == -1 || !this.ColumnModel.Columns[column].Enabled)
- {
- return;
- }
- if (e.Button == MouseButtons.Left)
- {
- this.FocusedCell = new CellPos(-1, -1);
-
- // don't bother going any further if the user
- // double clicked
- if (e.Clicks > 1)
- {
- return;
- }
- this.RaiseHeaderMouseDown(column, e);
-
- if (this.TableState == TableState.ColumnResizing)
- {
- Rectangle columnRect = this.ColumnModel.ColumnHeaderRect(column);
- int x = this.ClientToDisplayRect(e.X, e.Y).X;
- if (x <= columnRect.Left + Column.ResizePadding)
- {
- //column--;
- column = this.ColumnModel.PreviousVisibleColumn(column);
- }
-
- this.resizingColumnIndex = column;
- if (this.resizingColumnIndex != -1)
- {
- this.resizingColumnAnchor = this.ColumnModel.ColumnHeaderRect(column).Left;
- this.resizingColumnOffset = x - (this.resizingColumnAnchor + this.ColumnModel.Columns[column].Width);
- }
- }
- else
- {
- if (this.HeaderStyle != ColumnHeaderStyle.Clickable || !this.ColumnModel.Columns[column].Sortable)
- {
- return;
- }
-
- if (column == -1)
- {
- return;
- }
-
- if (this.pressedColumn != -1)
- {
- this.ColumnModel.Columns[this.pressedColumn].InternalColumnState = ColumnState.Normal;
- }
- this.pressedColumn = column;
- this.ColumnModel.Columns[column].InternalColumnState = ColumnState.Pressed;
- }
- return;
- }
- }
- #endregion
- #region Cells
- if (region == TableRegion.Cells)
- {
- if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)
- {
- return;
- }
- if (!this.IsValidCell(row, column) || !this.IsCellEnabled(row, column))
- {
- // clear selections
- this.TableModel.Selections.Clear();
-
- return;
- }
-
- this.FocusedCell = new CellPos(row, column);
-
- // don't bother going any further if the user
- // double clicked or we're not allowed to select
- if (e.Clicks > 1 || !this.AllowSelection)
- {
- return;
- }
- this.lastMouseDownCell.Row = row;
- this.lastMouseDownCell.Column = column;
- //
- this.RaiseCellMouseDown(new CellPos(row, column), e);
- if (!this.ColumnModel.Columns[column].Selectable)
- {
- return;
- }
- //
- if ((ModifierKeys & Keys.Shift) == Keys.Shift && this.MultiSelect)
- {
- if (e.Button == MouseButtons.Right)
- {
- return;
- }
-
- this.TableModel.Selections.AddShiftSelectedCell(row, column);
- return;
- }
- if ((ModifierKeys & Keys.Control) == Keys.Control && this.MultiSelect)
- {
- if (e.Button == MouseButtons.Right)
- {
- return;
- }
-
- if (this.TableModel.Selections.IsCellSelected(row, column))
- {
- this.TableModel.Selections.RemoveCell(row, column);
- }
- else
- {
- this.TableModel.Selections.AddCell(row, column);
- }
- return;
- }
- this.TableModel.Selections.SelectCell(row, column);
- }
- #endregion
- }
- #endregion
- #region MouseMove
- /// <summary>
- /// Raises the MouseMove event
- /// </summary>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected override void OnMouseMove(MouseEventArgs e)
- {
- base.OnMouseMove(e);
- // don't go any further if the table is editing
- if (this.TableState == TableState.Editing)
- {
- return;
- }
- // if the left mouse button is down, check if the LastMouseDownCell
- // references a valid cell. if it does, send the mouse move message
- // to the cell and then exit (this will stop other cells/headers
- // from getting the mouse move message even if the mouse is over
- // them - this seems consistent with the way windows does it for
- // other controls)
- if (e.Button == MouseButtons.Left)
- {
- if (!this.LastMouseDownCell.IsEmpty)
- {
- if (this.IsValidCell(this.LastMouseDownCell))
- {
- this.RaiseCellMouseMove(this.LastMouseDownCell, e);
- return;
- }
- }
- }
- // are we resizing a column?
- if (this.resizingColumnIndex != -1)
- {
- if (this.resizingColumnWidth != -1)
- {
- this.DrawReversibleLine(this.ColumnRect(this.resizingColumnIndex).Left + this.resizingColumnWidth);
- }
-
- // calculate the new width for the column
- int width = this.ClientToDisplayRect(e.X, e.Y).X - this.resizingColumnAnchor - this.resizingColumnOffset;
- // make sure the new width isn't smaller than the minimum allowed
- // column width, or larger than the maximum allowed column width
- if (width < Column.MinimumWidth)
- {
- width = Column.MinimumWidth;
- }
- else if (width > Column.MaximumWidth)
- {
- width = Column.MaximumWidth;
- }
- this.resizingColumnWidth = width;
-
- //this.ColumnModel.Columns[this.resizingColumnIndex].Width = width;
- this.DrawReversibleLine(this.ColumnRect(this.resizingColumnIndex).Left + this.resizingColumnWidth);
- return;
- }
- // work out the potential state of play
- this.CalcTableState(e.X, e.Y);
- TableRegion hitTest = this.HitTest(e.X, e.Y);
- #region ColumnHeader
- if (hitTest == TableRegion.ColumnHeader)
- {
- // this next bit is pretty complicated. need to work
- // out which column is displayed as pressed or hot
- // (so we have the same behaviour as a themed ListView
- // in Windows XP)
-
- int column = this.ColumnIndexAt(e.X, e.Y);
-
- // if this isn't the current hot column, reset the
- // hot columns state to normal and set this column
- // to be the hot column
- if (this.hotColumn != column)
- {
- if (this.hotColumn != -1)
- {
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Normal;
- this.RaiseHeaderMouseLeave(this.hotColumn);
- }
- if (this.TableState != TableState.ColumnResizing)
- {
- this.hotColumn = column;
- if (this.hotColumn != -1 && this.ColumnModel.Columns[column].Enabled)
- {
- this.ColumnModel.Columns[column].InternalColumnState = ColumnState.Hot;
- this.RaiseHeaderMouseEnter(column);
- }
- }
- }
- else
- {
- if (column != -1 && this.ColumnModel.Columns[column].Enabled)
- {
- this.RaiseHeaderMouseMove(column, e);
- }
- }
-
- // if this isn't the pressed column, then the pressed columns
- // state should be set back to normal
- if (this.pressedColumn != -1 && this.pressedColumn != column)
- {
- this.ColumnModel.Columns[this.pressedColumn].InternalColumnState = ColumnState.Normal;
- }
- // else if this is the pressed column and its state is not
- // pressed, then we had better set it
- else if (column != -1 && this.pressedColumn == column && this.ColumnModel.Columns[this.pressedColumn].ColumnState != ColumnState.Pressed)
- {
- this.ColumnModel.Columns[this.pressedColumn].InternalColumnState = ColumnState.Pressed;
- }
-
- // set the cursor to a resizing cursor if necesary
- if (this.TableState == TableState.ColumnResizing)
- {
- Rectangle columnRect = this.ColumnModel.ColumnHeaderRect(column);
- int x = this.ClientToDisplayRect(e.X, e.Y).X;
-
- this.Cursor = Cursors.VSplit;
- // if the left mouse button is down, we don't want
- // the resizing cursor so set it back to the default
- if (e.Button == MouseButtons.Left)
- {
- this.Cursor = Cursors.Default;
- }
-
- // if the mouse is in the left side of the column,
- // the first non-hidden column to the left needs to
- // become the hot column (so the user knows which
- // column would be resized if a resize action were
- // to take place
- if (x < columnRect.Left + Column.ResizePadding)
- {
- int col = column;
-
- while (col != 0)
- {
- col--;
-
- if (this.ColumnModel.Columns[col].Visible)
- {
- break;
- }
- }
- if (col != -1)
- {
- if (this.ColumnModel.Columns[col].Enabled)
- {
- if (this.hotColumn != -1)
- {
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Normal;
- }
-
- this.hotColumn = col;
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Hot;
- this.RaiseHeaderMouseEnter(col);
- }
- else
- {
- this.Cursor = Cursors.Default;
- }
- }
- }
- else
- {
- if (this.ColumnModel.Columns[column].Enabled)
- {
- // this mouse is in the right side of the column,
- // so this column needs to be dsiplayed hot
- this.hotColumn = column;
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Hot;
- }
- else
- {
- this.Cursor = Cursors.Default;
- }
- }
- }
- else
- {
- // we're not in a resizing area, so make sure the cursor
- // is the default cursor (we may have just come from a
- // resizing area)
- this.Cursor = Cursors.Default;
- }
- // reset the last cell the mouse was over
- this.ResetLastMouseCell();
- return;
- }
-
- #endregion
- // we're outside of the header, so if there is a hot column,
- // it need to be reset
- if (this.hotColumn != -1)
- {
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Normal;
-
- this.ResetHotColumn();
- }
- // if there is a pressed column, its state need to beset to normal
- if (this.pressedColumn != -1)
- {
- this.ColumnModel.Columns[this.pressedColumn].InternalColumnState = ColumnState.Normal;
- }
- #region Cells
- if (hitTest == TableRegion.Cells)
- {
- // find the cell the mouse is over
- CellPos cellPos = new CellPos(this.RowIndexAt(e.X, e.Y), this.ColumnIndexAt(e.X, e.Y));
- if (!cellPos.IsEmpty)
- {
- if (cellPos != this.lastMouseCell)
- {
- // check if the cell exists (ie is not null)
- if (this.IsValidCell(cellPos))
- {
- CellPos oldLastMouseCell = this.lastMouseCell;
-
- if (!oldLastMouseCell.IsEmpty)
- {
- this.ResetLastMouseCell();
- }
- this.lastMouseCell = cellPos;
- this.RaiseCellMouseEnter(cellPos);
- }
- else
- {
- this.ResetLastMouseCell();
- // make sure the cursor is the default cursor
- // (we may have just come from a resizing area in the header)
- this.Cursor = Cursors.Default;
- }
- }
- else
- {
- this.RaiseCellMouseMove(cellPos, e);
- }
- }
- else
- {
- this.ResetLastMouseCell();
- if (this.TableModel == null)
- {
- this.ResetToolTip();
- }
- }
- return;
- }
- else
- {
- this.ResetLastMouseCell();
- if (!this.lastMouseDownCell.IsEmpty)
- {
- this.RaiseCellMouseLeave(this.lastMouseDownCell);
- }
- if (this.TableModel == null)
- {
- this.ResetToolTip();
- }
- // make sure the cursor is the default cursor
- // (we may have just come from a resizing area in the header)
- this.Cursor = Cursors.Default;
- }
-
- #endregion
- }
- #endregion
- #region MouseLeave
- /// <summary>
- /// Raises the MouseLeave event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnMouseLeave(EventArgs e)
- {
- base.OnMouseLeave(e);
- // we're outside of the header, so if there is a hot column,
- // it needs to be reset (this shouldn't happen, but better
- // safe than sorry ;)
- if (this.hotColumn != -1)
- {
- this.ColumnModel.Columns[this.hotColumn].InternalColumnState = ColumnState.Normal;
- this.ResetHotColumn();
- }
- }
- #endregion
- #region MouseWheel
- /// <summary>
- /// Raises the MouseWheel event
- /// </summary>
- /// <param name="e">A MouseEventArgs that contains the event data</param>
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- base.OnMouseWheel(e);
- if (!this.Scrollable || (!this.HScroll && !this.VScroll))
- {
- return;
- }
- if (this.VScroll)
- {
- int newVal = this.vScrollBar.Value - ((e.Delta / 120) * SystemInformation.MouseWheelScrollLines);
- if (newVal < 0)
- {
- newVal = 0;
- }
- else if (newVal > this.vScrollBar.Maximum - this.vScrollBar.LargeChange + 1)
- {
- newVal = this.vScrollBar.Maximum - this.vScrollBar.LargeChange + 1;
- }
- this.VerticalScroll(newVal);
- this.vScrollBar.Value = newVal;
- }
- else if (this.HScroll)
- {
- int newVal = this.hScrollBar.Value - ((e.Delta / 120) * Column.MinimumWidth);
- if (newVal < 0)
- {
- newVal = 0;
- }
- else if (newVal > this.hScrollBar.Maximum - this.hScrollBar.LargeChange)
- {
- newVal = this.hScrollBar.Maximum - this.hScrollBar.LargeChange;
- }
- this.HorizontalScroll(newVal);
- this.hScrollBar.Value = newVal;
- }
- }
- #endregion
- #region MouseHover
- /// <summary>
- /// Raises the MouseHover event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnMouseHover(EventArgs e)
- {
- base.OnMouseHover(e);
- if (this.IsValidCell(this.LastMouseCell))
- {
- this.OnCellMouseHover(new CellMouseEventArgs(this.TableModel[this.LastMouseCell], this, this.LastMouseCell, this.CellRect(this.LastMouseCell)));
- }
- else if (this.hotColumn != -1)
- {
- this.OnHeaderMouseHover(new HeaderMouseEventArgs(this.ColumnModel.Columns[this.hotColumn], this, this.hotColumn, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(this.hotColumn))));
- }
- }
- #endregion
- #region Click
- /// <summary>
- /// Raises the Click event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnClick(EventArgs e)
- {
- base.OnClick(e);
- if (this.IsValidCell(this.LastMouseCell))
- {
- this.OnCellClick(new CellMouseEventArgs(this.TableModel[this.LastMouseCell], this, this.LastMouseCell, this.CellRect(this.LastMouseCell)));
- }
- else if (this.hotColumn != -1)
- {
- this.OnHeaderClick(new HeaderMouseEventArgs(this.ColumnModel.Columns[this.hotColumn], this, this.hotColumn, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(this.hotColumn))));
- }
- }
- /// <summary>
- /// Raises the DoubleClick event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected override void OnDoubleClick(EventArgs e)
- {
- base.OnDoubleClick(e);
- if (this.IsValidCell(this.LastMouseCell))
- {
- Rectangle cellRect = this.CellRect(this.LastMouseCell);
-
- this.OnCellDoubleClick(new CellMouseEventArgs(this.TableModel[this.LastMouseCell], this, this.LastMouseCell, this.CellRect(this.LastMouseCell)));
- }
- else if (this.hotColumn != -1)
- {
- this.OnHeaderDoubleClick(new HeaderMouseEventArgs(this.ColumnModel.Columns[this.hotColumn], this, this.hotColumn, this.DisplayRectToClient(this.ColumnModel.ColumnHeaderRect(this.hotColumn))));
- }
- }
- #endregion
- #endregion
- #region Paint
- /// <summary>
- /// Raises the PaintBackground event
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected override void OnPaintBackground(PaintEventArgs e)
- {
- base.OnPaintBackground(e);
- }
- /// <summary>
- /// Raises the Paint event
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected override void OnPaint(PaintEventArgs e)
- {
- // we'll do our own painting thanks
- //base.OnPaint(e);
- // check if we actually need to paint
- if (this.Width == 0 || this.Height == 0)
- {
- return;
- }
- if (this.ColumnModel != null)
- {
- // keep a record of the current clip region
- Region clip = e.Graphics.Clip;
-
- if (this.TableModel != null && this.TableModel.Rows.Count > 0)
- {
- this.OnPaintRows(e);
- // reset the clipping region
- e.Graphics.Clip = clip;
- }
- if (this.GridLines != GridLines.None)
- {
- this.OnPaintGrid(e);
- }
-
- if (this.HeaderStyle != ColumnHeaderStyle.None && this.ColumnModel.Columns.Count > 0)
- {
- if (this.HeaderRectangle.IntersectsWith(e.ClipRectangle))
- {
- this.OnPaintHeader(e);
- }
- }
- // reset the clipping region
- e.Graphics.Clip = clip;
- }
-
- this.OnPaintEmptyTableText(e);
- this.OnPaintBorder(e);
- }
- /// <summary>
- /// Draws a reversible line at the specified screen x-coordinate
- /// that is the height of the PseudoClientRect
- /// </summary>
- /// <param name="x">The screen x-coordinate of the reversible line
- /// to be drawn</param>
- private void DrawReversibleLine(int x)
- {
- Point start = this.PointToScreen(new Point(x, this.PseudoClientRect.Top));
-
- ControlPaint.DrawReversibleLine(start, new Point(start.X, start.Y + this.PseudoClientRect.Height), this.BackColor);
- }
-
- #region Border
- /// <summary>
- /// Paints the Table's border
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected void OnPaintBorder(PaintEventArgs e)
- {
- //e.Graphics.SetClip(e.ClipRectangle);
-
- if (this.BorderStyle == BorderStyle.Fixed3D)
- {
- if (ThemeManager.VisualStylesEnabled)
- {
- TextBoxStates state = TextBoxStates.Normal;
- if (!this.Enabled)
- {
- state = TextBoxStates.Disabled;
- }
-
- // draw the left border
- Rectangle clipRect = new Rectangle(0, 0, SystemInformation.Border3DSize.Width, this.Height);
- if (clipRect.IntersectsWith(e.ClipRectangle))
- {
- ThemeManager.DrawTextBox(e.Graphics, this.ClientRectangle, clipRect, state);
- }
-
- // draw the top border
- clipRect = new Rectangle(0, 0, this.Width, SystemInformation.Border3DSize.Height);
- if (clipRect.IntersectsWith(e.ClipRectangle))
- {
- ThemeManager.DrawTextBox(e.Graphics, this.ClientRectangle, clipRect, state);
- }
-
- // draw the right border
- clipRect = new Rectangle(this.Width-SystemInformation.Border3DSize.Width, 0, this.Width, this.Height);
- if (clipRect.IntersectsWith(e.ClipRectangle))
- {
- ThemeManager.DrawTextBox(e.Graphics, this.ClientRectangle, clipRect, state);
- }
-
- // draw the bottom border
- clipRect = new Rectangle(0, this.Height-SystemInformation.Border3DSize.Height, this.Width, SystemInformation.Border3DSize.Height);
- if (clipRect.IntersectsWith(e.ClipRectangle))
- {
- ThemeManager.DrawTextBox(e.Graphics, this.ClientRectangle, clipRect, state);
- }
- }
- else
- {
- ControlPaint.DrawBorder3D(e.Graphics, 0, 0, this.Width, this.Height, Border3DStyle.Sunken);
- }
- }
- else if (this.BorderStyle == BorderStyle.FixedSingle)
- {
- e.Graphics.DrawRectangle(Pens.Black, 0, 0, this.Width-1, this.Height-1);
- }
-
- if (this.HScroll && this.VScroll)
- {
- Rectangle rect = new Rectangle(this.Width - this.BorderWidth - SystemInformation.VerticalScrollBarWidth,
- this.Height - this.BorderWidth - SystemInformation.HorizontalScrollBarHeight,
- SystemInformation.VerticalScrollBarWidth,
- SystemInformation.HorizontalScrollBarHeight);
-
- if (rect.IntersectsWith(e.ClipRectangle))
- {
- e.Graphics.FillRectangle(SystemBrushes.Control, rect);
- }
- }
- }
- #endregion
- #region Cells
- /// <summary>
- /// Paints the Cell at the specified row and column indexes
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- /// <param name="row">The index of the row that contains the cell to be painted</param>
- /// <param name="column">The index of the column that contains the cell to be painted</param>
- /// <param name="cellRect">The bounding Rectangle of the Cell</param>
- protected void OnPaintCell(PaintEventArgs e, int row, int column, Rectangle cellRect)
- {
- if (row == 0 && column == 1)
- {
- column = 1;
- }
-
- // get the renderer for the cells column
- ICellRenderer renderer = this.ColumnModel.Columns[column].Renderer;
- if (renderer == null)
- {
- // get the default renderer for the column
- renderer = this.ColumnModel.GetCellRenderer(this.ColumnModel.Columns[column].GetDefaultRendererName());
- }
- // if the renderer is still null (which it shouldn't)
- // the get out of here
- if (renderer == null)
- {
- return;
- }
- PaintCellEventArgs pcea = new PaintCellEventArgs(e.Graphics, cellRect);
- pcea.Graphics.SetClip(Rectangle.Intersect(e.ClipRectangle, cellRect));
- if (column < this.TableModel.Rows[row].Cells.Count)
- {
- // is the cell selected
- bool selected = false;
- if (this.FullRowSelect)
- {
- selected = this.TableModel.Selections.IsRowSelected(row);
- }
- else
- {
- if (this.SelectionStyle == SelectionStyle.ListView)
- {
- if (this.TableModel.Selections.IsRowSelected(row) && this.ColumnModel.PreviousVisibleColumn(column) == -1)
- {
- selected = true;
- }
- }
- else if (this.SelectionStyle == SelectionStyle.Grid)
- {
- if (this.TableModel.Selections.IsCellSelected(row, column))
- {
- selected = true;
- }
- }
- }
- //
- bool editable = this.TableModel[row, column].Editable && this.TableModel.Rows[row].Editable && this.ColumnModel.Columns[column].Editable;
- bool enabled = this.TableModel[row, column].Enabled && this.TableModel.Rows[row].Enabled && this.ColumnModel.Columns[column].Enabled;
- // draw the cell
- pcea.SetCell(this.TableModel[row, column]);
- pcea.SetRow(row);
- pcea.SetColumn(column);
- pcea.SetTable(this);
- pcea.SetSelected(selected);
- pcea.SetFocused(this.Focused && this.FocusedCell.Row == row && this.FocusedCell.Column == column);
- pcea.SetSorted(column == this.lastSortedColumn);
- pcea.SetEditable(editable);
- pcea.SetEnabled(enabled);
- pcea.SetCellRect(cellRect);
- }
- else
- {
- // there isn't a cell for this column, so send a
- // null value for the cell and the renderer will
- // take care of the rest (it should draw an empty cell)
- pcea.SetCell(null);
- pcea.SetRow(row);
- pcea.SetColumn(column);
- pcea.SetTable(this);
- pcea.SetSelected(false);
- pcea.SetFocused(false);
- pcea.SetSorted(false);
- pcea.SetEditable(false);
- pcea.SetEnabled(false);
- pcea.SetCellRect(cellRect);
- }
- // let the user get the first crack at painting the cell
- this.OnBeforePaintCell(pcea);
-
- // only send to the renderer if the user hasn't
- // set the handled property
- if (!pcea.Handled)
- {
- renderer.OnPaintCell(pcea);
- }
- // let the user have another go
- this.OnAfterPaintCell(pcea);
- }
- /// <summary>
- /// Raises the BeforePaintCell event
- /// </summary>
- /// <param name="e">A PaintCellEventArgs that contains the event data</param>
- protected virtual void OnBeforePaintCell(PaintCellEventArgs e)
- {
- if (BeforePaintCell != null)
- {
- BeforePaintCell(this, e);
- }
- }
- /// <summary>
- /// Raises the AfterPaintCell event
- /// </summary>
- /// <param name="e">A PaintCellEventArgs that contains the event data</param>
- protected virtual void OnAfterPaintCell(PaintCellEventArgs e)
- {
- if (AfterPaintCell != null)
- {
- AfterPaintCell(this, e);
- }
- }
- #endregion
- #region Grid
- /// <summary>
- /// Paints the Table's grid
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected void OnPaintGrid(PaintEventArgs e)
- {
- if (this.GridLines == GridLines.None)
- {
- return;
- }
-
- //
- //e.Graphics.SetClip(e.ClipRectangle);
-
- if (this.ColumnModel == null || this.ColumnModel.Columns.Count == 0)
- {
- return;
- }
-
- //e.Graphics.SetClip(e.ClipRectangle);
- if (this.ColumnModel != null)
- {
- using (Pen gridPen = new Pen(this.GridColor))
- {
- //
- gridPen.DashStyle = (DashStyle) this.GridLineStyle;
- // check if we can draw column lines
- if ((this.GridLines & GridLines.Columns) == GridLines.Columns)
- {
- int right = this.DisplayRectangle.X;
- for (int i=0; i<this.ColumnModel.Columns.Count; i++)
- {
- if (this.ColumnModel.Columns[i].Visible)
- {
- right += this.ColumnModel.Columns[i].Width;
-
- if (right >= e.ClipRectangle.Left && right <= e.ClipRectangle.Right)
- {
- e.Graphics.DrawLine(gridPen, right-1, e.ClipRectangle.Top, right-1, e.ClipRectangle.Bottom);
- }
- }
- }
- }
- if (this.TableModel != null)
- {
- // check if we can draw row lines
- if ((this.GridLines & GridLines.Rows) == GridLines.Rows)
- {
- int y = this.CellDataRect.Y + this.RowHeight - 1;
-
- for (int i=y; i<=e.ClipRectangle.Bottom; i+=this.RowHeight)
- {
- if (i >= this.CellDataRect.Top)
- {
- e.Graphics.DrawLine(gridPen, e.ClipRectangle.Left, i, e.ClipRectangle.Right, i);
- }
- }
- }
- }
- }
- }
- }
- #endregion
- #region Header
- /// <summary>
- /// Paints the Table's Column headers
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected void OnPaintHeader(PaintEventArgs e)
- {
- // only bother if we actually get to paint something
- if (!this.HeaderRectangle.IntersectsWith(e.ClipRectangle))
- {
- return;
- }
- int xPos = this.DisplayRectangle.Left;
- bool needDummyHeader = true;
-
- //
- PaintHeaderEventArgs phea = new PaintHeaderEventArgs(e.Graphics, e.ClipRectangle);
- for (int i=0; i<this.ColumnModel.Columns.Count; i++)
- {
- // check that the column isn't hidden
- if (this.ColumnModel.Columns[i].Visible)
- {
- Rectangle colHeaderRect = new Rectangle(xPos, this.BorderWidth, this.ColumnModel.Columns[i].Width, this.HeaderHeight);
-
- // check that the column intersects with the clipping rect
- if (e.ClipRectangle.IntersectsWith(colHeaderRect))
- {
- // move and resize the headerRenderer
- this.headerRenderer.Bounds = new Rectangle(xPos, this.BorderWidth, this.ColumnModel.Columns[i].Width, this.HeaderHeight);
- // set the clipping area to the header renderers bounds
- phea.Graphics.SetClip(Rectangle.Intersect(e.ClipRectangle, this.headerRenderer.Bounds));
- // draw the column header
- phea.SetColumn(this.ColumnModel.Columns[i]);
- phea.SetColumnIndex(i);
- phea.SetTable(this);
- phea.SetHeaderStyle(this.HeaderStyle);
- phea.SetHeaderRect(this.headerRenderer.Bounds);
-
- // let the user get the first crack at painting the header
- this.OnBeforePaintHeader(phea);
-
- // only send to the renderer if the user hasn't
- // set the handled property
- if (!phea.Handled)
- {
- this.headerRenderer.OnPaintHeader(phea);
- }
- // let the user have another go
- this.OnAfterPaintHeader(phea);
- }
- // set the next column start position
- xPos += this.ColumnModel.Columns[i].Width;
- // if the next start poition is past the right edge
- // of the clipping rectangle then we don't need to
- // draw anymore
- if (xPos >= e.ClipRectangle.Right)
- {
- return;
- }
- // check is the next column position is past the
- // right edge of the table. if it is, get out of
- // here as we don't need to draw anymore columns
- if (xPos >= this.ClientRectangle.Width)
- {
- needDummyHeader = false;
- break;
- }
- }
- }
- if (needDummyHeader)
- {
- // move and resize the headerRenderer
- this.headerRenderer.Bounds = new Rectangle(xPos, this.BorderWidth, this.ClientRectangle.Width - xPos + 2, this.HeaderHeight);
- phea.Graphics.SetClip(Rectangle.Intersect(e.ClipRectangle, this.headerRenderer.Bounds));
- phea.SetColumn(null);
- phea.SetColumnIndex(-1);
- phea.SetTable(this);
- phea.SetHeaderStyle(this.HeaderStyle);
- phea.SetHeaderRect(this.headerRenderer.Bounds);
-
- // let the user get the first crack at painting the header
- this.OnBeforePaintHeader(phea);
-
- // only send to the renderer if the user hasn't
- // set the handled property
- if (!phea.Handled)
- {
- this.headerRenderer.OnPaintHeader(phea);
- }
- // let the user have another go
- this.OnAfterPaintHeader(phea);
- }
- }
- /// <summary>
- /// Raises the BeforePaintHeader event
- /// </summary>
- /// <param name="e">A PaintCellEventArgs that contains the event data</param>
- protected virtual void OnBeforePaintHeader(PaintHeaderEventArgs e)
- {
- if (BeforePaintHeader != null)
- {
- BeforePaintHeader(this, e);
- }
- }
- /// <summary>
- /// Raises the AfterPaintHeader event
- /// </summary>
- /// <param name="e">A PaintHeaderEventArgs that contains the event data</param>
- protected virtual void OnAfterPaintHeader(PaintHeaderEventArgs e)
- {
- if (AfterPaintHeader != null)
- {
- AfterPaintHeader(this, e);
- }
- }
- #endregion
- #region Rows
- /// <summary>
- /// Paints the Table's Rows
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected void OnPaintRows(PaintEventArgs e)
- {
- int xPos = this.DisplayRectangle.Left;
- int yPos = this.PseudoClientRect.Top;
- if (this.HeaderStyle != ColumnHeaderStyle.None)
- {
- yPos += this.HeaderHeight;
- }
- Rectangle rowRect = new Rectangle(xPos, yPos, this.ColumnModel.TotalColumnWidth, this.RowHeight);
- for (int i=this.TopIndex; i<Math.Min(this.TableModel.Rows.Count, this.TopIndex+this.VisibleRowCount+1); i++)
- {
- if (rowRect.IntersectsWith(e.ClipRectangle))
- {
- this.OnPaintRow(e, i, rowRect);
- }
- else if (rowRect.Top > e.ClipRectangle.Bottom)
- {
- break;
- }
- // move to the next row
- rowRect.Y += this.RowHeight;
- }
- //
- if (this.IsValidColumn(this.lastSortedColumn))
- {
- if (rowRect.Y < this.PseudoClientRect.Bottom)
- {
- Rectangle columnRect = this.ColumnRect(this.lastSortedColumn);
- columnRect.Y = rowRect.Y;
- columnRect.Height = this.PseudoClientRect.Bottom - rowRect.Y;
- if (columnRect.IntersectsWith(e.ClipRectangle))
- {
- columnRect.Intersect(e.ClipRectangle);
-
- e.Graphics.SetClip(columnRect);
- using (SolidBrush brush = new SolidBrush(this.SortedColumnBackColor))
- {
- e.Graphics.FillRectangle(brush, columnRect);
- }
- }
- }
- }
- }
- /// <summary>
- /// Paints the Row at the specified index
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- /// <param name="row">The index of the Row to be painted</param>
- /// <param name="rowRect">The bounding Rectangle of the Row to be painted</param>
- protected void OnPaintRow(PaintEventArgs e, int row, Rectangle rowRect)
- {
- Rectangle cellRect = new Rectangle(rowRect.X, rowRect.Y, 0, rowRect.Height);
- //e.Graphics.SetClip(rowRect);
- for (int i=0; i<this.ColumnModel.Columns.Count; i++)
- {
- if (this.ColumnModel.Columns[i].Visible)
- {
- cellRect.Width = this.ColumnModel.Columns[i].Width;
- if (cellRect.IntersectsWith(e.ClipRectangle))
- {
- this.OnPaintCell(e, row, i, cellRect);
- }
- else if (cellRect.Left > e.ClipRectangle.Right)
- {
- break;
- }
- cellRect.X += this.ColumnModel.Columns[i].Width;
- }
- }
- }
- #endregion
- #region Empty Table Text
- /// <summary>
- /// Paints the message that is displayed when the Table doen't
- /// contain any items
- /// </summary>
- /// <param name="e">A PaintEventArgs that contains the event data</param>
- protected void OnPaintEmptyTableText(PaintEventArgs e)
- {
- if (this.ColumnModel == null || this.RowCount == 0)
- {
- Rectangle client = this.CellDataRect;
- client.Y += 10;
- client.Height -= 10;
- StringFormat format = new StringFormat();
- format.Alignment = StringAlignment.Center;
-
- using (SolidBrush brush = new SolidBrush(this.ForeColor))
- {
- if (this.DesignMode)
- {
- if (this.ColumnModel == null || this.TableModel == null)
- {
- string text = null;
-
- if (this.ColumnModel == null)
- {
- if (this.TableModel == null)
- {
- text = "Table does not have a ColumnModel or TableModel";
- }
- else
- {
- text = "Table does not have a ColumnModel";
- }
- }
- else if (this.TableModel == null)
- {
- text = "Table does not have a TableModel";
- }
-
- e.Graphics.DrawString(text, this.Font, brush, client, format);
- }
- else if (this.TableModel != null && this.TableModel.Rows.Count == 0)
- {
- if (this.NoItemsText != null && this.NoItemsText.Length > 0)
- {
- e.Graphics.DrawString(this.NoItemsText, this.Font, brush, client, format);
- }
- }
- }
- else
- {
- if (this.NoItemsText != null && this.NoItemsText.Length > 0)
- {
- e.Graphics.DrawString(this.NoItemsText, this.Font, brush, client, format);
- }
- }
- }
- }
- }
- #endregion
- #endregion
- #region Rows
- /// <summary>
- /// Raises the RowPropertyChanged event
- /// </summary>
- /// <param name="e">A RowEventArgs that contains the event data</param>
- protected internal virtual void OnRowPropertyChanged(RowEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.InvalidateRow(e.Index);
-
- if (RowPropertyChanged != null)
- {
- RowPropertyChanged(e.Row, e);
- }
- }
- }
- /// <summary>
- /// Raises the CellAdded event
- /// </summary>
- /// <param name="e">A RowEventArgs that contains the event data</param>
- protected internal virtual void OnCellAdded(RowEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.InvalidateRow(e.Index);
- if (CellAdded != null)
- {
- CellAdded(e.Row, e);
- }
- }
- }
- /// <summary>
- /// Raises the CellRemoved event
- /// </summary>
- /// <param name="e">A RowEventArgs that contains the event data</param>
- protected internal virtual void OnCellRemoved(RowEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.InvalidateRow(e.Index);
- if (CellRemoved != null)
- {
- CellRemoved(this, e);
- }
- if (e.CellFromIndex == -1 && e.CellToIndex == -1)
- {
- if (this.FocusedCell.Row == e.Index)
- {
- this.focusedCell = CellPos.Empty;
- }
- }
- else
- {
- for (int i=e.CellFromIndex; i<=e.CellToIndex; i++)
- {
- if (this.FocusedCell.Row == e.Index && this.FocusedCell.Column == i)
- {
- this.focusedCell = CellPos.Empty;
- break;
- }
- }
- }
- }
- }
- #endregion
- #region Scrollbars
- /// <summary>
- /// Occurs when the Table's horizontal scrollbar is scrolled
- /// </summary>
- /// <param name="sender">The object that Raised the event</param>
- /// <param name="e">A ScrollEventArgs that contains the event data</param>
- protected void OnHorizontalScroll(object sender, ScrollEventArgs e)
- {
- // stop editing as the editor doesn't move while
- // the table scrolls
- if (this.IsEditing)
- {
- this.StopEditing();
- }
-
- if (this.CanRaiseEvents)
- {
- // non-solid row lines develop artifacts while scrolling
- // with the thumb so we invalidate the table once thumb
- // scrolling has finished to make them look nice again
- if (e.Type == ScrollEventType.ThumbPosition)
- {
- if (this.GridLineStyle != GridLineStyle.Solid)
- {
- if (this.GridLines == GridLines.Rows || this.GridLines == GridLines.Both)
- {
- this.Invalidate(this.CellDataRect, false);
- }
- }
- // same with the focus rect
- if (this.FocusedCell != CellPos.Empty)
- {
- this.Invalidate(this.CellRect(this.FocusedCell), false);
- }
- }
- else
- {
- this.HorizontalScroll(e.NewValue);
- }
- }
- }
- /// <summary>
- /// Occurs when the Table's vertical scrollbar is scrolled
- /// </summary>
- /// <param name="sender">The object that Raised the event</param>
- /// <param name="e">A ScrollEventArgs that contains the event data</param>
- protected void OnVerticalScroll(object sender, ScrollEventArgs e)
- {
- // stop editing as the editor doesn't move while
- // the table scrolls
- if (this.IsEditing)
- {
- this.StopEditing();
- }
-
- if (this.CanRaiseEvents)
- {
- // non-solid column lines develop artifacts while scrolling
- // with the thumb so we invalidate the table once thumb
- // scrolling has finished to make them look nice again
- if (e.Type == ScrollEventType.ThumbPosition)
- {
- if (this.GridLineStyle != GridLineStyle.Solid)
- {
- if (this.GridLines == GridLines.Columns || this.GridLines == GridLines.Both)
- {
- this.Invalidate(this.CellDataRect, false);
- }
- }
- }
- else
- {
- this.VerticalScroll(e.NewValue);
- }
- }
- }
- /// <summary>
- /// Handler for a ScrollBars GotFocus event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">An EventArgs that contains the event data</param>
- private void scrollBar_GotFocus(object sender, EventArgs e)
- {
- // don't let the scrollbars have focus
- // (appears to slow scroll speed otherwise)
- this.Focus();
- }
- #endregion
- #region Sorting
- /// <summary>
- /// Raises the BeginSort event
- /// </summary>
- /// <param name="e">A ColumnEventArgs that contains the event data</param>
- protected virtual void OnBeginSort(ColumnEventArgs e)
- {
- if (BeginSort != null)
- {
- BeginSort(this, e);
- }
- }
- /// <summary>
- /// Raises the EndSort event
- /// </summary>
- /// <param name="e">A ColumnEventArgs that contains the event data</param>
- protected virtual void OnEndSort(ColumnEventArgs e)
- {
- if (EndSort != null)
- {
- EndSort(this, e);
- }
- }
- #endregion
- #region TableModel
- /// <summary>
- /// Raises the TableModelChanged event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected internal virtual void OnTableModelChanged(EventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (TableModelChanged != null)
- {
- TableModelChanged(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the SelectionChanged event
- /// </summary>
- /// <param name="e">A TableModelEventArgs that contains the event data</param>
- protected internal virtual void OnSelectionChanged(SelectionEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- if (e.OldSelectionBounds != Rectangle.Empty)
- {
- Rectangle invalidateRect = new Rectangle(this.DisplayRectToClient(e.OldSelectionBounds.Location), e.OldSelectionBounds.Size);
- if (this.HeaderStyle != ColumnHeaderStyle.None)
- {
- invalidateRect.Y += this.HeaderHeight;
- }
-
- this.Invalidate(invalidateRect);
- }
- if (e.NewSelectionBounds != Rectangle.Empty)
- {
- Rectangle invalidateRect = new Rectangle(this.DisplayRectToClient(e.NewSelectionBounds.Location), e.NewSelectionBounds.Size);
- if (this.HeaderStyle != ColumnHeaderStyle.None)
- {
- invalidateRect.Y += this.HeaderHeight;
- }
-
- this.Invalidate(invalidateRect);
- }
-
- if (SelectionChanged != null)
- {
- SelectionChanged(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the RowHeightChanged event
- /// </summary>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected internal virtual void OnRowHeightChanged(EventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (RowHeightChanged != null)
- {
- RowHeightChanged(this, e);
- }
- }
- }
- /// <summary>
- /// Raises the RowAdded event
- /// </summary>
- /// <param name="e">A TableModelEventArgs that contains the event data</param>
- protected internal virtual void OnRowAdded(TableModelEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (RowAdded != null)
- {
- RowAdded(e.TableModel, e);
- }
- }
- }
- /// <summary>
- /// Raises the RowRemoved event
- /// </summary>
- /// <param name="e">A TableModelEventArgs that contains the event data</param>
- protected internal virtual void OnRowRemoved(TableModelEventArgs e)
- {
- if (this.CanRaiseEvents)
- {
- this.PerformLayout();
- this.Invalidate();
- if (RowRemoved != null)
- {
- RowRemoved(e.TableModel, e);
- }
- }
- }
- #endregion
- #endregion
- }
- }
|