| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584 |
- #nullable enable
- using System.Collections;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using Moq;
- using Terminal.Gui;
- using UnitTests;
- using Xunit;
- using Xunit.Abstractions;
- // ReSharper disable AccessToModifiedClosure
- namespace UnitTests_Parallelizable.ViewsTests;
- public class ListViewTests (ITestOutputHelper output)
- {
- private readonly ITestOutputHelper _output = output;
- [Fact]
- public void CollectionNavigatorMatcher_KeybindingsOverrideNavigator ()
- {
- ObservableCollection<string> source = ["apricot", "arm", "bat", "batman", "bates hotel", "candle"];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- lv.SetFocus ();
- lv.KeyBindings.Add (Key.B, Command.Down);
- Assert.Null (lv.SelectedItem);
- // Keys should be consumed to move down the navigation i.e. to apricot
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.Equal (0, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.Equal (1, lv.SelectedItem);
- // There is no keybinding for Key.C so it hits collection navigator i.e. we jump to candle
- Assert.True (lv.NewKeyDownEvent (Key.C));
- Assert.Equal (5, lv.SelectedItem);
- }
- [Fact]
- public void ListView_CollectionNavigatorMatcher_KeybindingsOverrideNavigator ()
- {
- ObservableCollection<string> source = ["apricot", "arm", "bat", "batman", "bates hotel", "candle"];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- lv.SetFocus ();
- lv.KeyBindings.Add (Key.B, Command.Down);
- Assert.Null (lv.SelectedItem);
- // Keys should be consumed to move down the navigation i.e. to apricot
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.Equal (0, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.Equal (1, lv.SelectedItem);
- // There is no keybinding for Key.C so it hits collection navigator i.e. we jump to candle
- Assert.True (lv.NewKeyDownEvent (Key.C));
- Assert.Equal (5, lv.SelectedItem);
- }
- [Fact]
- public void ListViewCollectionNavigatorMatcher_DefaultBehaviour ()
- {
- ObservableCollection<string> source = ["apricot", "arm", "bat", "batman", "bates hotel", "candle"];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- // Keys are consumed during navigation
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.True (lv.NewKeyDownEvent (Key.A));
- Assert.True (lv.NewKeyDownEvent (Key.T));
- Assert.Equal ("bat", (string)lv.Source.ToList () [lv.SelectedItem!.Value]!);
- }
- [Fact]
- public void ListViewCollectionNavigatorMatcher_IgnoreKeys ()
- {
- ObservableCollection<string> source = ["apricot", "arm", "bat", "batman", "bates hotel", "candle"];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- Mock<ICollectionNavigatorMatcher> matchNone = new ();
- matchNone.Setup (m => m.IsCompatibleKey (It.IsAny<Key> ()))
- .Returns (false);
- lv.KeystrokeNavigator.Matcher = matchNone.Object;
- // Keys are ignored because IsCompatibleKey returned false i.e. don't use these keys for navigation
- Assert.False (lv.NewKeyDownEvent (Key.B));
- Assert.False (lv.NewKeyDownEvent (Key.A));
- Assert.False (lv.NewKeyDownEvent (Key.T));
- // assert IsMatch never called
- matchNone.Verify (m => m.IsMatch (It.IsAny<string> (), It.IsAny<object> ()), Times.Never ());
- }
- [Fact]
- public void ListViewCollectionNavigatorMatcher_OverrideMatching ()
- {
- ObservableCollection<string> source = ["apricot", "arm", "bat", "batman", "bates hotel", "candle"];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- Mock<ICollectionNavigatorMatcher> matchNone = new ();
- matchNone.Setup (m => m.IsCompatibleKey (It.IsAny<Key> ()))
- .Returns (true);
- // Match any string starting with b to "candle" (psych!)
- matchNone.Setup (m => m.IsMatch (It.IsAny<string> (), It.IsAny<object> ()))
- .Returns ((string s, object key) => s.StartsWith ('B') && key?.ToString () == "candle");
- lv.KeystrokeNavigator.Matcher = matchNone.Object;
- // Keys are consumed during navigation
- Assert.True (lv.NewKeyDownEvent (Key.B));
- Assert.Equal (5, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.A));
- Assert.Equal (5, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.T));
- Assert.Equal (5, lv.SelectedItem);
- Assert.Equal ("candle", (string)lv.Source.ToList () [lv.SelectedItem!.Value]!);
- }
- #region ListView Tests (from ListViewTests.cs - parallelizable)
- [Fact]
- public void Constructors_Defaults ()
- {
- var lv = new ListView ();
- Assert.Null (lv.Source);
- Assert.True (lv.CanFocus);
- Assert.Null (lv.SelectedItem);
- Assert.False (lv.AllowsMultipleSelection);
- lv = new () { Source = new ListWrapper<string> (["One", "Two", "Three"]) };
- Assert.NotNull (lv.Source);
- Assert.Null (lv.SelectedItem);
- lv = new () { Source = new NewListDataSource () };
- Assert.NotNull (lv.Source);
- Assert.Null (lv.SelectedItem);
- lv = new ()
- {
- Y = 1, Width = 10, Height = 20, Source = new ListWrapper<string> (["One", "Two", "Three"])
- };
- Assert.NotNull (lv.Source);
- Assert.Null (lv.SelectedItem);
- Assert.Equal (new (0, 1, 10, 20), lv.Frame);
- lv = new () { Y = 1, Width = 10, Height = 20, Source = new NewListDataSource () };
- Assert.NotNull (lv.Source);
- Assert.Null (lv.SelectedItem);
- Assert.Equal (new (0, 1, 10, 20), lv.Frame);
- }
- private class NewListDataSource : IListDataSource
- {
- #pragma warning disable CS0067
- public event NotifyCollectionChangedEventHandler? CollectionChanged;
- #pragma warning restore CS0067
- public int Count => 0;
- public int Length => 0;
- public bool SuspendCollectionChangedEvent
- {
- get => throw new NotImplementedException ();
- set => throw new NotImplementedException ();
- }
- public bool IsMarked (int item) { throw new NotImplementedException (); }
- public void Render (
- ListView container,
- bool selected,
- int item,
- int col,
- int line,
- int width,
- int viewportX = 0
- )
- {
- throw new NotImplementedException ();
- }
- public void SetMark (int item, bool value) { throw new NotImplementedException (); }
- public IList ToList () { return new List<string> { "One", "Two", "Three" }; }
- public void Dispose () { throw new NotImplementedException (); }
- }
- [Fact]
- public void KeyBindings_Command ()
- {
- ObservableCollection<string> source = ["One", "Two", "Three"];
- var lv = new ListView { Height = 2, AllowsMarking = true, Source = new ListWrapper<string> (source) };
- lv.BeginInit ();
- lv.EndInit ();
- Assert.Null (lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.CursorDown));
- Assert.Equal (0, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.CursorUp));
- Assert.Equal (0, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.PageDown));
- Assert.Equal (2, lv.SelectedItem);
- Assert.Equal (2, lv.TopItem);
- Assert.True (lv.NewKeyDownEvent (Key.PageUp));
- Assert.Equal (0, lv.SelectedItem);
- Assert.Equal (0, lv.TopItem);
- Assert.False (lv.Source.IsMarked (lv.SelectedItem!.Value));
- Assert.True (lv.NewKeyDownEvent (Key.Space));
- Assert.True (lv.Source.IsMarked (lv.SelectedItem!.Value));
- var opened = false;
- lv.OpenSelectedItem += (s, _) => opened = true;
- Assert.True (lv.NewKeyDownEvent (Key.Enter));
- Assert.True (opened);
- Assert.True (lv.NewKeyDownEvent (Key.End));
- Assert.Equal (2, lv.SelectedItem);
- Assert.True (lv.NewKeyDownEvent (Key.Home));
- Assert.Equal (0, lv.SelectedItem);
- }
- [Fact]
- public void HotKey_Command_SetsFocus ()
- {
- var view = new ListView ();
- view.CanFocus = true;
- Assert.False (view.HasFocus);
- view.InvokeCommand (Command.HotKey);
- Assert.True (view.HasFocus);
- }
- [Fact]
- public void HotKey_Command_Does_Not_Accept ()
- {
- var listView = new ListView ();
- var accepted = false;
- listView.Accepting += OnAccepted;
- listView.InvokeCommand (Command.HotKey);
- Assert.False (accepted);
- return;
- void OnAccepted (object? sender, CommandEventArgs e) { accepted = true; }
- }
- [Fact]
- public void Accept_Command_Accepts_and_Opens_Selected_Item ()
- {
- ObservableCollection<string> source = ["One", "Two", "Three"];
- var listView = new ListView { Source = new ListWrapper<string> (source) };
- listView.SelectedItem = 0;
- var accepted = false;
- var opened = false;
- var selectedValue = string.Empty;
- listView.Accepting += Accepted;
- listView.OpenSelectedItem += OpenSelectedItem;
- listView.InvokeCommand (Command.Accept);
- Assert.True (accepted);
- Assert.True (opened);
- Assert.Equal (source [0], selectedValue);
- return;
- void OpenSelectedItem (object? sender, ListViewItemEventArgs e)
- {
- opened = true;
- selectedValue = e.Value!.ToString ();
- }
- void Accepted (object? sender, CommandEventArgs e) { accepted = true; }
- }
- [Fact]
- public void Accept_Cancel_Event_Prevents_OpenSelectedItem ()
- {
- ObservableCollection<string> source = ["One", "Two", "Three"];
- var listView = new ListView { Source = new ListWrapper<string> (source) };
- listView.SelectedItem = 0;
- var accepted = false;
- var opened = false;
- var selectedValue = string.Empty;
- listView.Accepting += Accepted;
- listView.OpenSelectedItem += OpenSelectedItem;
- listView.InvokeCommand (Command.Accept);
- Assert.True (accepted);
- Assert.False (opened);
- Assert.Equal (string.Empty, selectedValue);
- return;
- void OpenSelectedItem (object? sender, ListViewItemEventArgs e)
- {
- opened = true;
- selectedValue = e.Value!.ToString ();
- }
- void Accepted (object? sender, CommandEventArgs e)
- {
- accepted = true;
- e.Handled = true;
- }
- }
- [Fact]
- public void ListViewProcessKeyReturnValue_WithMultipleCommands ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two", "Three", "Four"]) };
- Assert.NotNull (lv.Source);
- // first item should be deselected by default
- Assert.Null (lv.SelectedItem);
- // bind shift down to move down twice in control
- lv.KeyBindings.Add (Key.CursorDown.WithShift, Command.Down, Command.Down);
- Key ev = Key.CursorDown.WithShift;
- Assert.True (lv.NewKeyDownEvent (ev), "The first time we move down 2 it should be possible");
- // After moving down twice from null we should be at 'Two'
- Assert.Equal (1, lv.SelectedItem);
- // clear the items
- lv.SetSource<string> (null);
- // Press key combo again - return should be false this time as none of the Commands are allowable
- Assert.False (lv.NewKeyDownEvent (ev), "We cannot move down so will not respond to this");
- }
- [Fact]
- public void AllowsMarking_True_SpaceWithShift_SelectsThenDown_SingleSelection ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two", "Three"]) };
- lv.AllowsMarking = true;
- lv.AllowsMultipleSelection = false;
- Assert.NotNull (lv.Source);
- // first item should be deselected by default
- Assert.Null (lv.SelectedItem);
- // nothing is ticked
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // view should indicate that it has accepted and consumed the event
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- // first item should now be selected
- Assert.Equal (0, lv.SelectedItem);
- // none of the items should be ticked
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- // second item should now be selected
- Assert.Equal (1, lv.SelectedItem);
- // first item only should be ticked
- Assert.True (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem);
- Assert.False (lv.Source.IsMarked (0));
- Assert.True (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem); // cannot move down any further
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.True (lv.Source.IsMarked (2)); // but can toggle marked
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem); // cannot move down any further
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2)); // untoggle toggle marked
- }
- [Fact]
- public void AllowsMarking_True_SpaceWithShift_SelectsThenDown_MultipleSelection ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two", "Three"]) };
- lv.AllowsMarking = true;
- lv.AllowsMultipleSelection = true;
- Assert.NotNull (lv.Source);
- // first item should be deselected by default
- Assert.Null (lv.SelectedItem);
- // nothing is ticked
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // view should indicate that it has accepted and consumed the event
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- // first item should now be selected
- Assert.Equal (0, lv.SelectedItem);
- // none of the items should be ticked
- Assert.False (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- // second item should now be selected
- Assert.Equal (1, lv.SelectedItem);
- // first item only should be ticked
- Assert.True (lv.Source.IsMarked (0));
- Assert.False (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem);
- Assert.True (lv.Source.IsMarked (0));
- Assert.True (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2));
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem); // cannot move down any further
- Assert.True (lv.Source.IsMarked (0));
- Assert.True (lv.Source.IsMarked (1));
- Assert.True (lv.Source.IsMarked (2)); // but can toggle marked
- // Press key combo again
- Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift));
- Assert.Equal (2, lv.SelectedItem); // cannot move down any further
- Assert.True (lv.Source.IsMarked (0));
- Assert.True (lv.Source.IsMarked (1));
- Assert.False (lv.Source.IsMarked (2)); // untoggle toggle marked
- }
- [Fact]
- public void ListWrapper_StartsWith ()
- {
- ListWrapper<string> lw = new (["One", "Two", "Three"]);
- Assert.Equal (1, lw.StartsWith ("t"));
- Assert.Equal (1, lw.StartsWith ("tw"));
- Assert.Equal (2, lw.StartsWith ("th"));
- Assert.Equal (1, lw.StartsWith ("T"));
- Assert.Equal (1, lw.StartsWith ("TW"));
- Assert.Equal (2, lw.StartsWith ("TH"));
- lw = new (["One", "Two", "Three"]);
- Assert.Equal (1, lw.StartsWith ("t"));
- Assert.Equal (1, lw.StartsWith ("tw"));
- Assert.Equal (2, lw.StartsWith ("th"));
- Assert.Equal (1, lw.StartsWith ("T"));
- Assert.Equal (1, lw.StartsWith ("TW"));
- Assert.Equal (2, lw.StartsWith ("TH"));
- }
- [Fact]
- public void OnEnter_Does_Not_Throw_Exception ()
- {
- var lv = new ListView ();
- var top = new View ();
- top.Add (lv);
- Exception exception = Record.Exception (() => lv.SetFocus ());
- Assert.Null (exception);
- }
- [Fact]
- public void SelectedItem_Get_Set ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two", "Three"]) };
- Assert.Null (lv.SelectedItem);
- Assert.Throws<ArgumentException> (() => lv.SelectedItem = 3);
- Exception exception = Record.Exception (() => lv.SelectedItem = null);
- Assert.Null (exception);
- }
- [Fact]
- public void SetSource_Preserves_ListWrapper_Instance_If_Not_Null ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two"]) };
- Assert.NotNull (lv.Source);
- lv.SetSource<string> (null);
- Assert.NotNull (lv.Source);
- lv.Source = null;
- Assert.Null (lv.Source);
- lv = new () { Source = new ListWrapper<string> (["One", "Two"]) };
- Assert.NotNull (lv.Source);
- lv.SetSourceAsync<string> (null);
- Assert.NotNull (lv.Source);
- }
- [Fact]
- public void SettingEmptyKeybindingThrows ()
- {
- var lv = new ListView { Source = new ListWrapper<string> (["One", "Two", "Three"]) };
- Assert.Throws<ArgumentException> (() => lv.KeyBindings.Add (Key.Space));
- }
- [Fact]
- public void CollectionChanged_Event ()
- {
- var added = 0;
- var removed = 0;
- ObservableCollection<string> source = [];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- lv.CollectionChanged += (sender, args) =>
- {
- if (args.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- else if (args.Action == NotifyCollectionChangedAction.Remove)
- {
- removed++;
- }
- };
- for (var i = 0; i < 3; i++)
- {
- source.Add ($"Item{i}");
- }
- Assert.Equal (3, added);
- Assert.Equal (0, removed);
- added = 0;
- for (var i = 0; i < 3; i++)
- {
- source.Remove (source [0]);
- }
- Assert.Equal (0, added);
- Assert.Equal (3, removed);
- Assert.Empty (source);
- }
- [Fact]
- public void CollectionChanged_Event_Is_Only_Subscribed_Once ()
- {
- var added = 0;
- var removed = 0;
- var otherActions = 0;
- IList<string> source1 = [];
- var lv = new ListView { Source = new ListWrapper<string> (new (source1)) };
- lv.CollectionChanged += (sender, args) =>
- {
- if (args.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- else if (args.Action == NotifyCollectionChangedAction.Remove)
- {
- removed++;
- }
- else
- {
- otherActions++;
- }
- };
- ObservableCollection<string> source2 = [];
- lv.Source = new ListWrapper<string> (source2);
- ObservableCollection<string> source3 = [];
- lv.Source = new ListWrapper<string> (source3);
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Add ($"Item{i}");
- source2.Add ($"Item{i}");
- source3.Add ($"Item{i}");
- }
- Assert.Equal (3, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- added = 0;
- for (var i = 0; i < 3; i++)
- {
- source1.Remove (source1 [0]);
- source2.Remove (source2 [0]);
- source3.Remove (source3 [0]);
- }
- Assert.Equal (0, added);
- Assert.Equal (3, removed);
- Assert.Equal (0, otherActions);
- Assert.Empty (source1);
- Assert.Empty (source2);
- Assert.Empty (source3);
- }
- [Fact]
- public void CollectionChanged_Event_UnSubscribe_Previous_If_New_Is_Null ()
- {
- var added = 0;
- var removed = 0;
- var otherActions = 0;
- ObservableCollection<string> source1 = [];
- var lv = new ListView { Source = new ListWrapper<string> (source1) };
- lv.CollectionChanged += (sender, args) =>
- {
- if (args.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- else if (args.Action == NotifyCollectionChangedAction.Remove)
- {
- removed++;
- }
- else
- {
- otherActions++;
- }
- };
- lv.Source = new ListWrapper<string> (null);
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Add ($"Item{i}");
- }
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Remove (source1 [0]);
- }
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- Assert.Empty (source1);
- }
- [Fact]
- public void ListWrapper_CollectionChanged_Event_Is_Only_Subscribed_Once ()
- {
- var added = 0;
- var removed = 0;
- var otherActions = 0;
- ObservableCollection<string> source1 = [];
- ListWrapper<string> lw = new (source1);
- lw.CollectionChanged += (sender, args) =>
- {
- if (args.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- else if (args.Action == NotifyCollectionChangedAction.Remove)
- {
- removed++;
- }
- else
- {
- otherActions++;
- }
- };
- ObservableCollection<string> source2 = [];
- lw = new (source2);
- ObservableCollection<string> source3 = [];
- lw = new (source3);
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Add ($"Item{i}");
- source2.Add ($"Item{i}");
- source3.Add ($"Item{i}");
- }
- Assert.Equal (3, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- added = 0;
- for (var i = 0; i < 3; i++)
- {
- source1.Remove (source1 [0]);
- source2.Remove (source2 [0]);
- source3.Remove (source3 [0]);
- }
- Assert.Equal (0, added);
- Assert.Equal (3, removed);
- Assert.Equal (0, otherActions);
- Assert.Empty (source1);
- Assert.Empty (source2);
- Assert.Empty (source3);
- }
- [Fact]
- public void ListWrapper_CollectionChanged_Event_UnSubscribe_Previous_Is_Disposed ()
- {
- var added = 0;
- var removed = 0;
- var otherActions = 0;
- ObservableCollection<string> source1 = [];
- ListWrapper<string> lw = new (source1);
- lw.CollectionChanged += Lw_CollectionChanged;
- lw.Dispose ();
- lw = new (null);
- Assert.Equal (0, lw.Count);
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Add ($"Item{i}");
- }
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- for (var i = 0; i < 3; i++)
- {
- source1.Remove (source1 [0]);
- }
- Assert.Equal (0, added);
- Assert.Equal (0, removed);
- Assert.Equal (0, otherActions);
- Assert.Empty (source1);
- void Lw_CollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- }
- }
- [Fact]
- public void ListWrapper_SuspendCollectionChangedEvent_ResumeSuspendCollectionChangedEvent_Tests ()
- {
- var added = 0;
- ObservableCollection<string> source = [];
- ListWrapper<string> lw = new (source);
- lw.CollectionChanged += Lw_CollectionChanged;
- lw.SuspendCollectionChangedEvent = true;
- for (var i = 0; i < 3; i++)
- {
- source.Add ($"Item{i}");
- }
- Assert.Equal (0, added);
- Assert.Equal (3, lw.Count);
- Assert.Equal (3, source.Count);
- lw.SuspendCollectionChangedEvent = false;
- for (var i = 3; i < 6; i++)
- {
- source.Add ($"Item{i}");
- }
- Assert.Equal (3, added);
- Assert.Equal (6, lw.Count);
- Assert.Equal (6, source.Count);
- void Lw_CollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- }
- }
- [Fact]
- public void ListView_SuspendCollectionChangedEvent_ResumeSuspendCollectionChangedEvent_Tests ()
- {
- var added = 0;
- ObservableCollection<string> source = [];
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- lv.CollectionChanged += Lw_CollectionChanged;
- lv.SuspendCollectionChangedEvent ();
- for (var i = 0; i < 3; i++)
- {
- source.Add ($"Item{i}");
- }
- Assert.Equal (0, added);
- Assert.Equal (3, lv.Source.Count);
- Assert.Equal (3, source.Count);
- lv.ResumeSuspendCollectionChangedEvent ();
- for (var i = 3; i < 6; i++)
- {
- source.Add ($"Item{i}");
- }
- Assert.Equal (3, added);
- Assert.Equal (6, lv.Source.Count);
- Assert.Equal (6, source.Count);
- void Lw_CollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- added++;
- }
- }
- }
- #endregion
- [Fact]
- public void Clicking_On_Border_Is_Ignored ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- var selected = "";
- var lv = new ListView
- {
- Height = 5,
- Width = 7,
- BorderStyle = LineStyle.Single
- };
- lv.SetSource (["One", "Two", "Three", "Four"]);
- lv.SelectedItemChanged += (s, e) => selected = e.Value.ToString ();
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- //AutoInitShutdownAttribute.RunIteration ();
- Assert.Equal (new (1), lv.Border!.Thickness);
- Assert.Null (lv.SelectedItem);
- Assert.Equal ("", lv.Text);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌─────┐
- │One │
- │Two │
- │Three│
- └─────┘",
- _output, app?.Driver);
- app?.Mouse.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked });
- Assert.Equal ("", selected);
- Assert.Null (lv.SelectedItem);
- app?.Mouse.RaiseMouseEvent (
- new ()
- {
- ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked
- });
- Assert.Equal ("One", selected);
- Assert.Equal (0, lv.SelectedItem);
- app?.Mouse.RaiseMouseEvent (
- new ()
- {
- ScreenPosition = new (1, 2), Flags = MouseFlags.Button1Clicked
- });
- Assert.Equal ("Two", selected);
- Assert.Equal (1, lv.SelectedItem);
- app?.Mouse.RaiseMouseEvent (
- new ()
- {
- ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked
- });
- Assert.Equal ("Three", selected);
- Assert.Equal (2, lv.SelectedItem);
- app?.Mouse.RaiseMouseEvent (
- new ()
- {
- ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Clicked
- });
- Assert.Equal ("Three", selected);
- Assert.Equal (2, lv.SelectedItem);
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void Ensures_Visibility_SelectedItem_On_MoveDown_And_MoveUp ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- app.Driver?.SetScreenSize (12, 12);
- ObservableCollection<string> source = [];
- for (var i = 0; i < 20; i++)
- {
- source.Add ($"Line{i}");
- }
- var lv = new ListView { Width = Dim.Fill (), Height = Dim.Fill (), Source = new ListWrapper<string> (source) };
- var win = new Window ();
- win.Add (lv);
- var top = new Toplevel ();
- top.Add (win);
- app.Begin (top);
- Assert.Null (lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.ScrollVertical (10));
- app.LayoutAndDraw ();
- Assert.Null (lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line10 │
- │Line11 │
- │Line12 │
- │Line13 │
- │Line14 │
- │Line15 │
- │Line16 │
- │Line17 │
- │Line18 │
- │Line19 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveDown ());
- app.LayoutAndDraw ();
- Assert.Equal (0, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveEnd ());
- app.LayoutAndDraw ();
- Assert.Equal (19, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line10 │
- │Line11 │
- │Line12 │
- │Line13 │
- │Line14 │
- │Line15 │
- │Line16 │
- │Line17 │
- │Line18 │
- │Line19 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.ScrollVertical (-20));
- app.LayoutAndDraw ();
- Assert.Equal (19, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveDown ());
- app.LayoutAndDraw ();
- Assert.Equal (19, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line10 │
- │Line11 │
- │Line12 │
- │Line13 │
- │Line14 │
- │Line15 │
- │Line16 │
- │Line17 │
- │Line18 │
- │Line19 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.ScrollVertical (-20));
- app.LayoutAndDraw ();
- Assert.Equal (19, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveDown ());
- app.LayoutAndDraw ();
- Assert.Equal (19, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line10 │
- │Line11 │
- │Line12 │
- │Line13 │
- │Line14 │
- │Line15 │
- │Line16 │
- │Line17 │
- │Line18 │
- │Line19 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveHome ());
- app.LayoutAndDraw ();
- Assert.Equal (0, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.ScrollVertical (20));
- app.LayoutAndDraw ();
- Assert.Equal (0, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line19 │
- │ │
- │ │
- │ │
- │ │
- │ │
- │ │
- │ │
- │ │
- │ │
- └──────────┘",
- _output, app.Driver
- );
- Assert.True (lv.MoveUp ());
- app.LayoutAndDraw ();
- Assert.Equal (0, lv.SelectedItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ┌──────────┐
- │Line0 │
- │Line1 │
- │Line2 │
- │Line3 │
- │Line4 │
- │Line5 │
- │Line6 │
- │Line7 │
- │Line8 │
- │Line9 │
- └──────────┘",
- _output, app.Driver
- );
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void EnsureSelectedItemVisible_SelectedItem ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- app.Driver?.SetScreenSize (12, 12);
- ObservableCollection<string> source = [];
- for (var i = 0; i < 10; i++)
- {
- source.Add ($"Item {i}");
- }
- var lv = new ListView { Width = 10, Height = 5, Source = new ListWrapper<string> (source) };
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- Item 0
- Item 1
- Item 2
- Item 3
- Item 4",
- _output, app.Driver
- );
- // EnsureSelectedItemVisible is auto enabled on the OnSelectedChanged
- lv.SelectedItem = 6;
- app.LayoutAndDraw ();
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6",
- _output, app.Driver
- );
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void EnsureSelectedItemVisible_Top ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- IDriver? driver = app.Driver;
- driver.SetScreenSize (8, 2);
- ObservableCollection<string> source = ["First", "Second"];
- var lv = new ListView { Width = Dim.Fill (), Height = 1, Source = new ListWrapper<string> (source) };
- lv.SelectedItem = 1;
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- Assert.Equal ("Second ", GetContents (0));
- Assert.Equal (new (' ', 7), GetContents (1));
- lv.MoveUp ();
- lv.Draw ();
- Assert.Equal ("First ", GetContents (0));
- Assert.Equal (new (' ', 7), GetContents (1));
- string GetContents (int line)
- {
- var item = "";
- for (var i = 0; i < 7; i++)
- {
- item += app.Driver?.Contents [line, i].Rune;
- }
- return item;
- }
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void LeftItem_TopItem_Tests ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- app.Driver?.SetScreenSize (12, 12);
- ObservableCollection<string> source = [];
- for (var i = 0; i < 5; i++)
- {
- source.Add ($"Item {i}");
- }
- var lv = new ListView
- {
- X = 1,
- Source = new ListWrapper<string> (source)
- };
- lv.Height = lv.Source.Count;
- lv.Width = lv.MaxLength;
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- Item 0
- Item 1
- Item 2
- Item 3
- Item 4",
- _output, app.Driver);
- lv.LeftItem = 1;
- lv.TopItem = 1;
- app.LayoutAndDraw ();
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- tem 1
- tem 2
- tem 3
- tem 4",
- _output, app.Driver);
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void RowRender_Event ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- var rendered = false;
- ObservableCollection<string> source = ["one", "two", "three"];
- var lv = new ListView { Width = Dim.Fill (), Height = Dim.Fill () };
- lv.RowRender += (s, _) => rendered = true;
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- Assert.False (rendered);
- lv.SetSource (source);
- lv.Draw ();
- Assert.True (rendered);
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void Vertical_ScrollBar_Hides_And_Shows_As_Needed ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- var lv = new ListView
- {
- Width = 10,
- Height = 3
- };
- lv.VerticalScrollBar.AutoShow = true;
- lv.SetSource (["One", "Two", "Three", "Four", "Five"]);
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- Assert.True (lv.VerticalScrollBar.Visible);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- One ▲
- Two █
- Three ▼",
- _output, app?.Driver);
- lv.Height = 5;
- app?.LayoutAndDraw ();
- Assert.False (lv.VerticalScrollBar.Visible);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- One
- Two
- Three
- Four
- Five ",
- _output, app?.Driver);
- top.Dispose ();
- app?.Shutdown ();
- }
- [Fact]
- public void Mouse_Wheel_Scrolls ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- var lv = new ListView
- {
- Width = 10,
- Height = 3,
- };
- lv.SetSource (["One", "Two", "Three", "Four", "Five"]);
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- // Initially, we are at the top.
- Assert.Equal (0, lv.TopItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- One
- Two
- Three",
- _output, app?.Driver);
- // Scroll down
- app.Mouse.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.WheeledDown });
- app.LayoutAndDraw ();
- Assert.Equal (1, lv.TopItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- Two
- Three
- Four ",
- _output, app?.Driver);
- // Scroll up
- app.Mouse.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.WheeledUp });
- app.LayoutAndDraw ();
- Assert.Equal (0, lv.TopItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- One
- Two
- Three",
- _output, app?.Driver);
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public void SelectedItem_With_Source_Null_Does_Nothing ()
- {
- var lv = new ListView ();
- Assert.Null (lv.Source);
- // should not throw
- lv.SelectedItem = 0;
- Assert.Null (lv.SelectedItem);
- }
- [Fact]
- public void Horizontal_Scroll ()
- {
- IApplication? app = Application.Create ();
- app.Init ("fake");
- var lv = new ListView
- {
- Width = 10,
- Height = 3,
- };
- lv.SetSource (["One", "Two", "Three - long", "Four", "Five"]);
- var top = new Toplevel ();
- top.Add (lv);
- app.Begin (top);
- Assert.Equal (0, lv.LeftItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- One
- Two
- Three - lo",
- _output, app?.Driver);
- lv.ScrollHorizontal (1);
- app.LayoutAndDraw ();
- Assert.Equal (1, lv.LeftItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ne
- wo
- hree - lon",
- _output, app?.Driver);
- // Scroll right with mouse
- app.Mouse.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.WheeledRight });
- app.LayoutAndDraw ();
- Assert.Equal (2, lv.LeftItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- e
- o
- ree - long",
- _output, app?.Driver);
- // Scroll left with mouse
- app.Mouse.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.WheeledLeft });
- app.LayoutAndDraw ();
- Assert.Equal (1, lv.LeftItem);
- DriverAssert.AssertDriverContentsWithFrameAre (
- @"
- ne
- wo
- hree - lon",
- _output, app?.Driver);
- top.Dispose ();
- app.Shutdown ();
- }
- [Fact]
- public async Task SetSourceAsync_SetsSource ()
- {
- var lv = new ListView ();
- var source = new ObservableCollection<string> { "One", "Two", "Three" };
- await lv.SetSourceAsync (source);
- Assert.NotNull (lv.Source);
- Assert.Equal (3, lv.Source.Count);
- }
- [Fact]
- public void AllowsMultipleSelection_Set_To_False_Unmarks_All_But_Selected ()
- {
- var lv = new ListView { AllowsMarking = true, AllowsMultipleSelection = true };
- var source = new ListWrapper<string> (["One", "Two", "Three"]);
- lv.Source = source;
- lv.SelectedItem = 0;
- source.SetMark (0, true);
- source.SetMark (1, true);
- source.SetMark (2, true);
- Assert.True (source.IsMarked (0));
- Assert.True (source.IsMarked (1));
- Assert.True (source.IsMarked (2));
- lv.AllowsMultipleSelection = false;
- Assert.True (source.IsMarked (0));
- Assert.False (source.IsMarked (1));
- Assert.False (source.IsMarked (2));
- }
- [Fact]
- public void Source_CollectionChanged_Remove ()
- {
- var source = new ObservableCollection<string> { "One", "Two", "Three" };
- var lv = new ListView { Source = new ListWrapper<string> (source) };
- lv.SelectedItem = 2;
- Assert.Equal (2, lv.SelectedItem);
- Assert.Equal (3, lv.Source.Count);
- source.RemoveAt (0);
- Assert.Equal (2, lv.Source.Count);
- Assert.Equal (1, lv.SelectedItem);
- source.RemoveAt (1);
- Assert.Equal (1, lv.Source.Count);
- Assert.Equal (0, lv.SelectedItem);
- }
- }
|