| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Linq;
- using System.Reactive.Disposables;
- using System.Threading.Tasks;
- using Avalonia.Collections;
- using Avalonia.Controls.Presenters;
- using Avalonia.Controls.Primitives;
- using Avalonia.Controls.Selection;
- using Avalonia.Controls.Templates;
- using Avalonia.Data;
- using Avalonia.Input;
- using Avalonia.Input.Platform;
- using Avalonia.Interactivity;
- using Avalonia.Layout;
- using Avalonia.Markup.Data;
- using Avalonia.Platform;
- using Avalonia.Styling;
- using Avalonia.Threading;
- using Avalonia.UnitTests;
- using Avalonia.VisualTree;
- using Moq;
- using Xunit;
- namespace Avalonia.Controls.UnitTests.Primitives
- {
- public partial class SelectingItemsControlTests
- {
- private MouseTestHelper _helper = new MouseTestHelper();
- [Fact]
- public void SelectedIndex_Should_Initially_Be_Minus_1()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void Item_IsSelected_Should_Initially_Be_False()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- Assert.False(items[0].IsSelected);
- Assert.False(items[1].IsSelected);
- }
- [Fact]
- public void Setting_SelectedItem_Should_Set_Item_IsSelected_True()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedItem = items[1];
- Assert.False(items[0].IsSelected);
- Assert.True(items[1].IsSelected);
- }
- [Fact]
- public void Setting_SelectedItem_Before_ApplyTemplate_Should_Set_Item_IsSelected_True()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.SelectedItem = items[1];
- Prepare(target);
- Assert.False(items[0].IsSelected);
- Assert.True(items[1].IsSelected);
- }
- [Fact]
- public void SelectedIndex_Should_Be_Minus_1_After_Initialize()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new ListBox();
- target.BeginInit();
- target.ItemsSource = items;
- target.Template = Template();
- target.EndInit();
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void SelectedIndex_Should_Be_Minus_1_Without_Initialize()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new ListBox();
- target.ItemsSource = items;
- target.Template = Template();
- target.DataContext = new object();
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void SelectedIndex_Should_Be_0_After_Initialize_With_AlwaysSelected()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new ListBox();
- target.BeginInit();
- target.SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected;
- target.ItemsSource = items;
- target.Template = Template();
- target.EndInit();
- Prepare(target);
- Assert.Equal(0, target.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectedIndex_During_Initialize_Should_Select_Item_When_AlwaysSelected_Is_Used()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected
- };
- listBox.BeginInit();
- listBox.SelectedIndex = 1;
- var items = new AvaloniaList<string>();
- listBox.ItemsSource = items;
- items.Add("A");
- items.Add("B");
- items.Add("C");
- listBox.EndInit();
- Prepare(listBox);
- Assert.Equal("B", listBox.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedIndex_Before_Initialize_Should_Retain_Selection()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Single,
- ItemsSource = new[] { "foo", "bar", "baz" },
- SelectedIndex = 1
- };
- listBox.BeginInit();
- listBox.EndInit();
- Assert.Equal(1, listBox.SelectedIndex);
- Assert.Equal("bar", listBox.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedIndex_During_Initialize_Should_Take_Priority_Over_Previous_Value()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Single,
- ItemsSource = new[] { "foo", "bar", "baz" },
- SelectedIndex = 2
- };
- listBox.BeginInit();
- listBox.SelectedIndex = 1;
- listBox.EndInit();
- Assert.Equal(1, listBox.SelectedIndex);
- Assert.Equal("bar", listBox.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedItem_Before_Initialize_Should_Retain_Selection()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Single,
- ItemsSource = new[] { "foo", "bar", "baz" },
- SelectedItem = "bar"
- };
- listBox.BeginInit();
- listBox.EndInit();
- Assert.Equal(1, listBox.SelectedIndex);
- Assert.Equal("bar", listBox.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedItems_Before_Initialize_Should_Retain_Selection()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Multiple,
- ItemsSource = new[] { "foo", "bar", "baz" },
- };
- var selected = new[] { "foo", "bar" };
- foreach (var v in selected)
- {
- listBox.SelectedItems.Add(v);
- }
- listBox.BeginInit();
- listBox.EndInit();
- Assert.Equal(selected, listBox.SelectedItems);
- }
- [Fact]
- public void Setting_SelectedItems_During_Initialize_Should_Take_Priority_Over_Previous_Value()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Multiple,
- ItemsSource = new[] { "foo", "bar", "baz" },
- };
- var selected = new[] { "foo", "bar" };
- foreach (var v in new[] { "bar", "baz" })
- {
- listBox.SelectedItems.Add(v);
- }
- listBox.BeginInit();
- listBox.SelectedItems = new AvaloniaList<object>(selected);
- listBox.EndInit();
- Assert.Equal(selected, listBox.SelectedItems);
- }
- [Fact]
- public void Setting_SelectedIndex_Before_Initialize_With_AlwaysSelected_Should_Retain_Selection()
- {
- var listBox = new ListBox
- {
- SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected,
- ItemsSource = new[] { "foo", "bar", "baz" },
- SelectedIndex = 1
- };
- listBox.BeginInit();
- listBox.EndInit();
- Assert.Equal(1, listBox.SelectedIndex);
- Assert.Equal("bar", listBox.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedIndex_Before_ApplyTemplate_Should_Set_Item_IsSelected_True()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.SelectedIndex = 1;
- Prepare(target);
- Assert.False(items[0].IsSelected);
- Assert.True(items[1].IsSelected);
- }
- [Fact]
- public void Setting_SelectedItem_Should_Set_SelectedIndex()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedItem = items[1];
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- }
- [Fact]
- public void SelectedIndex_Item_Is_Updated_As_Items_Removed_When_Last_Item_Is_Selected()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "FooBar"
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedItem = items[2];
- Assert.Equal(items[2], target.SelectedItem);
- Assert.Equal(2, target.SelectedIndex);
- items.RemoveAt(0);
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectedItem_To_Not_Present_Item_Should_Clear_Selection()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedItem = items[1];
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- target.SelectedItem = new Item();
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectedIndex_Should_Set_SelectedItem()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedIndex_Out_Of_Bounds_Should_Clear_Selection()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedIndex = 2;
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectedItem_To_Non_Existent_Item_Should_Clear_Selection()
- {
- var target = new SelectingItemsControl
- {
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedItem = new Item();
- Assert.Equal(-1, target.SelectedIndex);
- Assert.Null(target.SelectedItem);
- }
- [Fact]
- public void Adding_Selected_Item_Should_Update_Selection()
- {
- var items = new AvaloniaList<Item>(new[]
- {
- new Item(),
- new Item(),
- });
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- items.Add(new Item { IsSelected = true });
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal(items[2], target.SelectedItem);
- }
- [Fact]
- public void Setting_Items_To_Null_Should_Clear_Selection()
- {
- var items = new AvaloniaList<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- target.ItemsSource = null;
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void Removing_Selected_Item_Should_Clear_Selection()
- {
- var items = new AvaloniaList<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
- var removed = items[1];
- items.RemoveAt(1);
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Empty(receivedArgs.AddedItems);
- Assert.Equal(new[] { removed }, receivedArgs.RemovedItems);
- Assert.False(items.Single().IsSelected);
- }
- [Fact]
- public void Removing_Selected_Item_Should_Update_Selection_With_AlwaysSelected()
- {
- var item0 = new Item();
- var item1 = new Item();
- var items = new AvaloniaList<Item>
- {
- item0,
- item1,
- };
- var target = new TestSelector
- {
- ItemsSource = items,
- Template = Template(),
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- Prepare(target);
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
- items.RemoveAt(1);
- Assert.Same(item0, target.SelectedItem);
- Assert.Equal(0, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Equal(new[] { item0 }, receivedArgs.AddedItems);
- Assert.Equal(new[] { item1 }, receivedArgs.RemovedItems);
- Assert.True(items.Single().IsSelected);
- }
- [Fact]
- public void Removing_Selected_Item_Should_Clear_Selection_With_BeginInit()
- {
- var items = new AvaloniaList<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl();
- target.BeginInit();
- target.ItemsSource = items;
- target.Template = Template();
- target.EndInit();
- Prepare(target);
- target.SelectedIndex = 0;
- Assert.Equal(items[0], target.SelectedItem);
- Assert.Equal(0, target.SelectedIndex);
- SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
- var removed = items[0];
- items.RemoveAt(0);
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Empty(receivedArgs.AddedItems);
- Assert.Equal(new[] { removed }, receivedArgs.RemovedItems);
- Assert.False(items.Single().IsSelected);
- }
- [Fact]
- public void Replacing_Selected_Item_Should_Clear_Selection()
- {
- var items = new AvaloniaList<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
- var removed = items[1];
- items[1] = new Item();
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Empty(receivedArgs.AddedItems);
- Assert.Equal(new[] { removed }, receivedArgs.RemovedItems);
- Assert.All(items, x => Assert.False(x.IsSelected));
- }
- [Fact]
- public void Moving_Selected_Item_Should_Clear_Selection()
- {
- var items = new AvaloniaList<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- SelectionChangedEventArgs receivedArgs = null;
- target.SelectionChanged += (_, args) => receivedArgs = args;
- var removed = items[1];
- items.Move(1, 0);
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Empty(receivedArgs.AddedItems);
- Assert.Equal(new[] { removed }, receivedArgs.RemovedItems);
- Assert.All(items, x => Assert.False(x.IsSelected));
- }
- [Fact]
- public void Resetting_Items_Collection_Should_Clear_Selection()
- {
- // Need to use ObservableCollection here as AvaloniaList signals a Clear as an
- // add + remove.
- var items = new ObservableCollection<Item>
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedIndex = 1;
- Assert.Equal(items[1], target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- items.Clear();
- Assert.Null(target.SelectedItem);
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void Raising_IsSelectedChanged_On_Item_Should_Update_Selection()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedItem = items[1];
- Assert.False(items[0].IsSelected);
- Assert.True(items[1].IsSelected);
- items[0].IsSelected = true;
- items[0].RaiseEvent(new RoutedEventArgs(SelectingItemsControl.IsSelectedChangedEvent));
- Assert.Equal(0, target.SelectedIndex);
- Assert.Equal(items[0], target.SelectedItem);
- Assert.True(items[0].IsSelected);
- Assert.False(items[1].IsSelected);
- }
- [Fact]
- public void Clearing_IsSelected_And_Raising_IsSelectedChanged_On_Item_Should_Update_Selection()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- Prepare(target);
- target.SelectedItem = items[1];
- Assert.False(items[0].IsSelected);
- Assert.True(items[1].IsSelected);
- items[1].IsSelected = false;
- items[1].RaiseEvent(new RoutedEventArgs(SelectingItemsControl.IsSelectedChangedEvent));
- Assert.Equal(-1, target.SelectedIndex);
- Assert.Null(target.SelectedItem);
- }
- [Fact]
- public void Raising_IsSelectedChanged_On_Someone_Elses_Item_Should_Not_Update_Selection()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- target.ApplyTemplate();
- target.SelectedItem = items[1];
- var notChild = new Item
- {
- IsSelected = true,
- };
- target.RaiseEvent(new RoutedEventArgs
- {
- RoutedEvent = SelectingItemsControl.IsSelectedChangedEvent,
- Source = notChild,
- });
- Assert.Equal(target.SelectedItem, items[1]);
- }
- [Fact]
- public void Setting_SelectedIndex_Should_Raise_SelectionChanged_Event()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- var called = false;
- target.SelectionChanged += (s, e) =>
- {
- Assert.Same(items[1], e.AddedItems.Cast<object>().Single());
- Assert.Empty(e.RemovedItems);
- called = true;
- };
- target.SelectedIndex = 1;
- Assert.True(called);
- }
- [Fact]
- public void Clearing_SelectedIndex_Should_Raise_SelectionChanged_Event()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- SelectedIndex = 1,
- };
- Prepare(target);
- var called = false;
- target.SelectionChanged += (s, e) =>
- {
- Assert.Same(items[1], e.RemovedItems.Cast<object>().Single());
- Assert.Empty(e.AddedItems);
- called = true;
- };
- target.SelectedIndex = -1;
- Assert.True(called);
- }
- [Fact]
- public void Setting_SelectedIndex_Should_Raise_PropertyChanged_Events()
- {
- var items = new ObservableCollection<string> { "foo", "bar", "baz" };
- var target = new TestSelector
- {
- ItemsSource = items,
- Template = Template(),
- };
- var selectedIndexRaised = 0;
- var selectedItemRaised = 0;
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == SelectingItemsControl.SelectedIndexProperty)
- {
- Assert.Equal(-1, e.OldValue);
- Assert.Equal(1, e.NewValue);
- ++selectedIndexRaised;
- }
- else if (e.Property == SelectingItemsControl.SelectedItemProperty)
- {
- Assert.Null(e.OldValue);
- Assert.Equal("bar", e.NewValue);
- ++selectedItemRaised;
- }
- };
- target.SelectedIndex = 1;
- Assert.Equal(1, selectedIndexRaised);
- Assert.Equal(1, selectedItemRaised);
- }
- [Fact]
- public void Removing_Selected_Item_Should_Raise_PropertyChanged_Events()
- {
- var items = new ObservableCollection<string> { "foo", "bar", "baz" };
- var target = new TestSelector
- {
- ItemsSource = items,
- Template = Template(),
- };
- var selectedIndexRaised = 0;
- var selectedItemRaised = 0;
- target.SelectedIndex = 1;
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == SelectingItemsControl.SelectedIndexProperty)
- {
- Assert.Equal(1, e.OldValue);
- Assert.Equal(-1, e.NewValue);
- ++selectedIndexRaised;
- }
- else if (e.Property == SelectingItemsControl.SelectedItemProperty)
- {
- Assert.Equal("bar", e.OldValue);
- Assert.Null(e.NewValue);
- }
- };
- items.RemoveAt(1);
- Assert.Equal(1, selectedIndexRaised);
- Assert.Equal(0, selectedItemRaised);
- }
- [Fact]
- public void Removing_Selected_Item0_Should_Raise_PropertyChanged_Events_With_AlwaysSelected()
- {
- var items = new ObservableCollection<string> { "foo", "bar", "baz" };
- var target = new TestSelector
- {
- ItemsSource = items,
- Template = Template(),
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var selectedIndexRaised = 0;
- var selectedItemRaised = 0;
- target.SelectedIndex = 0;
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == SelectingItemsControl.SelectedIndexProperty)
- {
- ++selectedIndexRaised;
- }
- else if (e.Property == SelectingItemsControl.SelectedItemProperty)
- {
- Assert.Equal("foo", e.OldValue);
- Assert.Equal("bar", e.NewValue);
- ++selectedItemRaised;
- }
- };
- items.RemoveAt(0);
- Assert.Equal(0, selectedIndexRaised);
- Assert.Equal(1, selectedItemRaised);
- }
- [Fact]
- public void Removing_Selected_Item1_Should_Raise_PropertyChanged_Events_With_AlwaysSelected()
- {
- var items = new ObservableCollection<string> { "foo", "bar", "baz" };
- var target = new TestSelector
- {
- ItemsSource = items,
- Template = Template(),
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var selectedIndexRaised = 0;
- var selectedItemRaised = 0;
- target.SelectedIndex = 1;
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == SelectingItemsControl.SelectedIndexProperty)
- {
- Assert.Equal(1, e.OldValue);
- Assert.Equal(0, e.NewValue);
- ++selectedIndexRaised;
- }
- else if (e.Property == SelectingItemsControl.SelectedItemProperty)
- {
- Assert.Equal("bar", e.OldValue);
- Assert.Equal("foo", e.NewValue);
- }
- };
- items.RemoveAt(1);
- Assert.Equal(1, selectedIndexRaised);
- Assert.Equal(0, selectedItemRaised);
- }
- [Fact]
- public void Removing_Item_Before_Selection_Should_Raise_PropertyChanged_Events()
- {
- var items = new ObservableCollection<string> { "foo", "bar", "baz" };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- };
- var selectedIndexRaised = 0;
- var selectedItemRaised = 0;
- target.SelectedIndex = 1;
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == SelectingItemsControl.SelectedIndexProperty)
- {
- Assert.Equal(1, e.OldValue);
- Assert.Equal(0, e.NewValue);
- ++selectedIndexRaised;
- }
- else if (e.Property == SelectingItemsControl.SelectedItemProperty)
- {
- ++selectedItemRaised;
- }
- };
- items.RemoveAt(0);
- Assert.Equal(1, selectedIndexRaised);
- Assert.Equal(0, selectedItemRaised);
- }
- [Fact]
- public void Order_Of_Setting_Items_And_SelectedIndex_During_Initialization_Should_Not_Matter()
- {
- using var app = Start();
- var items = new[] { "Foo", "Bar" };
- var target = new SelectingItemsControl();
- ((ISupportInitialize)target).BeginInit();
- target.SelectedIndex = 1;
- target.ItemsSource = items;
- ((ISupportInitialize)target).EndInit();
- Prepare(target);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
- }
- [Fact]
- public void Order_Of_Setting_Items_And_SelectedItem_During_Initialization_Should_Not_Matter()
- {
- using var app = Start();
- var items = new[] { "Foo", "Bar" };
- var target = new SelectingItemsControl();
- ((ISupportInitialize)target).BeginInit();
- target.SelectedItem = "Bar";
- target.ItemsSource = items;
- ((ISupportInitialize)target).EndInit();
- Prepare(target);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
- }
- [Fact]
- public void Changing_DataContext_Should_Not_Clear_Nested_ViewModel_SelectedItem()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- };
- var vm = new MasterViewModel
- {
- Child = new ChildViewModel
- {
- Items = items,
- SelectedItem = items[1],
- }
- };
- var target = new SelectingItemsControl { DataContext = vm };
- var itemsBinding = new Binding("Child.Items");
- var selectedBinding = new Binding("Child.SelectedItem");
- target.Bind(SelectingItemsControl.ItemsSourceProperty, itemsBinding);
- target.Bind(SelectingItemsControl.SelectedItemProperty, selectedBinding);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Same(vm.Child.SelectedItem, target.SelectedItem);
- items = new[]
- {
- new Item { Value = "Item1" },
- new Item { Value = "Item2" },
- new Item { Value = "Item3" },
- };
- vm = new MasterViewModel
- {
- Child = new ChildViewModel
- {
- Items = items,
- SelectedItem = items[2],
- }
- };
- target.DataContext = vm;
- Assert.Equal(2, target.SelectedIndex);
- Assert.Same(vm.Child.SelectedItem, target.SelectedItem);
- }
- [Fact]
- public void Nested_ListBox_Does_Not_Change_Parent_SelectedIndex()
- {
- SelectingItemsControl nested;
- var root = new SelectingItemsControl
- {
- Template = Template(),
- ItemsSource = new Control[]
- {
- new Border(),
- nested = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "foo", "bar" },
- SelectedIndex = 1,
- }
- },
- SelectedIndex = 0,
- };
- root.ApplyTemplate();
- root.Presenter.ApplyTemplate();
- nested.ApplyTemplate();
- nested.Presenter.ApplyTemplate();
- Assert.Equal(0, root.SelectedIndex);
- Assert.Equal(1, nested.SelectedIndex);
- nested.SelectedIndex = 0;
- Assert.Equal(0, root.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectedItem_With_Pointer_Should_Set_TabOnceActiveElement()
- {
- using (UnitTestApplication.Start())
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz " },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[1]);
- var panel = target.Presenter.Panel;
- Assert.Equal(
- KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel),
- panel.Children[1]);
- }
- }
- [Fact]
- public void Removing_SelectedItem_Should_Clear_TabOnceActiveElement()
- {
- using (UnitTestApplication.Start())
- {
- var items = new ObservableCollection<string>(new[] { "Foo", "Bar", "Baz " });
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
- Prepare(target);
- _helper.Down(target.Presenter.Panel.Children[1]);
- items.RemoveAt(1);
- var panel = target.Presenter.Panel;
- Assert.Null(KeyboardNavigation.GetTabOnceActiveElement((InputElement)panel));
- }
- }
- [Fact]
- public void Resetting_Items_Collection_Should_Retain_Selection()
- {
- var itemsMock = new Mock<List<string>>();
- var itemsMockAsINCC = itemsMock.As<INotifyCollectionChanged>();
- itemsMock.Object.AddRange(new[] { "Foo", "Bar", "Baz" });
- var target = new SelectingItemsControl
- {
- ItemsSource = itemsMock.Object
- };
- target.SelectedIndex = 1;
- itemsMockAsINCC.Raise(e => e.CollectionChanged += null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
- Assert.True(target.SelectedIndex == 1);
- }
- [Fact]
- public void Binding_With_DelayedBinding_And_Initialization_Where_DataContext_Is_Root_Works()
- {
- // Test for #1932.
- var root = new RootWithItems();
- root.BeginInit();
- root.DataContext = root;
- var target = new ListBox();
- target.BeginInit();
- root.Child = target;
- DelayedBinding.Add(target, ItemsControl.ItemsSourceProperty, new Binding(nameof(RootWithItems.Items)));
- DelayedBinding.Add(target, ListBox.SelectedItemProperty, new Binding(nameof(RootWithItems.Selected)));
- target.EndInit();
- root.EndInit();
- Assert.Equal("b", target.SelectedItem);
- }
- [Fact]
- public void Mode_For_SelectedIndex_Is_TwoWay_By_Default()
- {
- var items = new[]
- {
- new Item(),
- new Item(),
- new Item(),
- };
- var vm = new MasterViewModel
- {
- Child = new ChildViewModel
- {
- Items = items,
- SelectedIndex = 1,
- }
- };
- var target = new SelectingItemsControl { DataContext = vm };
- var itemsBinding = new Binding("Child.Items");
- var selectedIndBinding = new Binding("Child.SelectedIndex");
- target.Bind(SelectingItemsControl.ItemsSourceProperty, itemsBinding);
- target.Bind(SelectingItemsControl.SelectedIndexProperty, selectedIndBinding);
- Assert.Equal(1, target.SelectedIndex);
- target.SelectedIndex = 2;
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal(2, vm.Child.SelectedIndex);
- }
- [Fact]
- public void Should_Select_Correct_Item_When_Duplicate_Items_Are_Present()
- {
- using (UnitTestApplication.Start())
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
- Assert.Equal(3, target.SelectedIndex);
- }
- }
- [Fact]
- public void Should_Apply_Selected_Pseudoclass_To_Correct_Item_When_Duplicate_Items_Are_Present()
- {
- using (UnitTestApplication.Start())
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
- Prepare(target);
- _helper.Down((Interactive)target.Presenter.Panel.Children[3]);
- Assert.Equal(new[] { ":pressed", ":selected" }, target.Presenter.Panel.Children[3].Classes);
- }
- }
- [Fact]
- public void Adding_Item_Before_SelectedItem_Should_Update_SelectedIndex()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectedIndex = 1,
- };
- Prepare(target);
- items.Insert(0, "Qux");
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
- }
- [Fact]
- public void Removing_Item_Before_SelectedItem_Should_Update_SelectedIndex()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectedIndex = 1,
- };
- Prepare(target);
- items.RemoveAt(0);
- Assert.Equal(0, target.SelectedIndex);
- Assert.Equal("Bar", target.SelectedItem);
- }
- [Fact]
- public void Binding_SelectedIndex_Selects_Correct_Item()
- {
- // Issue #4496 (part 2)
- var items = new ObservableCollection<string>();
- var other = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- [!ListBox.SelectedIndexProperty] = other[!ListBox.SelectedIndexProperty],
- };
- Prepare(other);
- Prepare(target);
- items.Add("Foo");
- Assert.Equal(0, other.SelectedIndex);
- Assert.Equal(0, target.SelectedIndex);
- }
- [Fact]
- public void Binding_SelectedItem_Selects_Correct_Item()
- {
- // Issue #4496 (part 2)
- var items = new ObservableCollection<string>();
- var other = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- [!ListBox.SelectedItemProperty] = other[!ListBox.SelectedItemProperty],
- };
- Prepare(target);
- other.ApplyTemplate();
- other.Presenter.ApplyTemplate();
- items.Add("Foo");
- Assert.Equal(0, other.SelectedIndex);
- Assert.Equal(0, target.SelectedIndex);
- }
- [Fact]
- public void Replacing_Selected_Item_Should_Update_SelectedItem()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectedIndex = 1,
- };
- Prepare(target);
- items[1] = "Qux";
- Assert.Equal(-1, target.SelectedIndex);
- Assert.Null(target.SelectedItem);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Causes_Scroll_To_SelectedItem()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- };
- var raised = false;
- Prepare(target);
- target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
- target.SelectedIndex = 2;
- Assert.True(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Causes_Scroll_To_Initial_SelectedItem()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- };
- var raised = false;
- target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
- target.SelectedIndex = 2;
- Prepare(target);
- Assert.True(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_On_Reset_Works()
- {
- // Issue #3148
- using (UnitTestApplication.Start(TestServices.StyledWindow))
- {
- var items = new ResettingCollection(100);
- var target = new ListBox
- {
- ItemsSource = items,
- ItemTemplate = new FuncDataTemplate<string>((x, _) =>
- new TextBlock
- {
- Text = x,
- Width = 100,
- Height = 10
- }),
- AutoScrollToSelectedItem = true,
- };
- var root = new TestRoot(true, target);
- root.Measure(new Size(100, 100));
- root.Arrange(new Rect(0, 0, 100, 100));
- Assert.True(target.Presenter.Panel.Children.Count > 0);
- Assert.True(target.Presenter.Panel.Children.Count < 100);
- target.SelectedItem = "Item99";
- // #3148 triggered here.
- items.Reset(new[] { "Item99" });
- Layout(target);
- Assert.Equal(0, target.SelectedIndex);
- Assert.Equal(1, target.Presenter.Panel.Children.Where(x => x.IsVisible).Count());
- }
- }
- [Fact]
- public void AutoScrollToSelectedItem_Scrolls_When_Reattached_To_Visual_Tree_If_Selection_Changed_While_Detached_From_Visual_Tree()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectedIndex = 2,
- };
- var raised = false;
- Prepare(target);
- var root = (TestRoot)target.Parent;
- target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
- root.Child = null;
- target.SelectedIndex = 1;
- root.Child = target;
- Assert.True(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Doesnt_Scroll_If_Reattached_To_Visual_Tree_With_No_Selection_Change()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- SelectedIndex = 2,
- };
- var raised = false;
- Prepare(target);
- var root = (TestRoot)target.Parent;
- target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
- root.Child = null;
- root.Child = target;
- Assert.False(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Causes_Scroll_When_Turned_On()
- {
- var items = new ObservableCollection<string>
- {
- "Foo",
- "Bar",
- "Baz"
- };
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- AutoScrollToSelectedItem = false,
- };
- Prepare(target);
- var raised = false;
- target.AddHandler(Control.RequestBringIntoViewEvent, (s, e) => raised = true);
- target.SelectedIndex = 2;
- Assert.False(raised);
- target.AutoScrollToSelectedItem = true;
- Assert.True(raised);
- }
- [Fact]
- public void Can_Set_Both_SelectedItem_And_SelectedItems_During_Initialization()
- {
- // Issue #2969.
- var target = new ListBox();
- var selectedItems = new List<object>();
- target.BeginInit();
- target.Template = Template();
- target.ItemsSource = new[] { "Foo", "Bar", "Baz" };
- target.SelectedItems = selectedItems;
- target.SelectedItem = "Bar";
- target.EndInit();
- Prepare(target);
- Assert.Equal("Bar", target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Same(selectedItems, target.SelectedItems);
- Assert.Equal(new[] { "Bar" }, selectedItems);
- }
- [Fact(Timeout = 2000)]
- public async Task MoveSelection_Wrap_Does_Not_Hang_With_No_Focusable_Controls()
- {
- // Issue #3094.
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem { Focusable = false },
- new ListBoxItem { Focusable = false },
- },
- SelectedIndex = 0,
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- // Timeout in xUnit doesn't work with synchronous methods so we need to apply hack below.
- // https://github.com/xunit/xunit/issues/2222
- await Task.Run(() => target.MoveSelection(NavigationDirection.Next, true));
- }
- [Fact]
- public void MoveSelection_Skips_Non_Focusable_Controls_When_Moving_To_Last_Item()
- {
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem(),
- new ListBoxItem { Focusable = false },
- }
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- target.MoveSelection(NavigationDirection.Last, true);
- Assert.Equal(0, target.SelectedIndex);
- }
- [Fact]
- public void MoveSelection_Skips_Non_Focusable_Controls_When_Moving_To_First_Item()
- {
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem { Focusable = false },
- new ListBoxItem(),
- }
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- target.MoveSelection(NavigationDirection.Last, true);
- Assert.Equal(1, target.SelectedIndex);
- }
- [Fact(Timeout = 2000)]
- public async Task MoveSelection_Does_Not_Hang_When_All_Items_Are_Non_Focusable_And_We_Move_To_First_Item()
- {
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem { Focusable = false },
- new ListBoxItem { Focusable = false },
- }
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- // Timeout in xUnit doesn't work with synchronous methods so we need to apply hack below.
- // https://github.com/xunit/xunit/issues/2222
- await Task.Run(() => target.MoveSelection(NavigationDirection.First, true));
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact(Timeout = 2000)]
- public async Task MoveSelection_Does_Not_Hang_When_All_Items_Are_Non_Focusable_And_We_Move_To_Last_Item()
- {
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem { Focusable = false },
- new ListBoxItem { Focusable = false },
- }
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- // Timeout in xUnit doesn't work with synchronous methods so we need to apply hack below.
- // https://github.com/xunit/xunit/issues/2222
- await Task.Run(() => target.MoveSelection(NavigationDirection.Last, true));
- Assert.Equal(-1, target.SelectedIndex);
- }
- [Fact]
- public void MoveSelection_Does_Select_Disabled_Controls()
- {
- // Issue #3426.
- var target = new TestSelector
- {
- Template = Template(),
- Items =
- {
- new ListBoxItem(),
- new ListBoxItem { IsEnabled = false },
- },
- SelectedIndex = 0,
- };
- target.Measure(new Size(100, 100));
- target.Arrange(new Rect(0, 0, 100, 100));
- target.MoveSelection(NavigationDirection.Next, true);
- Assert.Equal(0, target.SelectedIndex);
- }
- [Fact]
- public void Pre_Selecting_Item_Should_Set_Selection_After_It_Was_Added_When_AlwaysSelected()
- {
- var target = new TestSelector(SelectionMode.AlwaysSelected)
- {
- Template = Template()
- };
- var second = new Item { IsSelected = true };
- var items = new AvaloniaList<object>
- {
- new Item(),
- second
- };
- target.ItemsSource = items;
- Prepare(target);
- Assert.Equal(second, target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- }
- [Fact]
- public void Setting_SelectionMode_Should_Update_SelectionModel()
- {
- var target = new TestSelector();
- var model = target.Selection;
- Assert.True(model.SingleSelect);
- target.SelectionMode = SelectionMode.Multiple;
- Assert.False(model.SingleSelect);
- }
- [Fact]
- public void Does_The_Best_It_Can_With_AutoSelecting_ViewModel()
- {
- // Tests the following scenario:
- //
- // - Items changes from empty to having 1 item
- // - ViewModel auto-selects item 0 in CollectionChanged
- // - SelectionModel receives CollectionChanged
- // - And so adjusts the selected item from 0 to 1, which is past the end of the items.
- //
- // There's not much we can do about this situation because the order in which
- // CollectionChanged handlers are called can't be known (the problem also exists with
- // WPF). The best we can do is not select an invalid index.
- var vm = new SelectionViewModel();
- vm.Items.CollectionChanged += (s, e) =>
- {
- if (vm.SelectedIndex == -1 && vm.Items.Count > 0)
- {
- vm.SelectedIndex = 0;
- }
- };
- var target = new ListBox
- {
- [!ListBox.ItemsSourceProperty] = new Binding("Items"),
- [!ListBox.SelectedIndexProperty] = new Binding("SelectedIndex"),
- DataContext = vm,
- };
- Prepare(target);
- vm.Items.Add("foo");
- vm.Items.Add("bar");
- Assert.Equal(0, target.SelectedIndex);
- Assert.Equal(new[] { 0 }, target.Selection.SelectedIndexes);
- Assert.Equal("foo", target.SelectedItem);
- Assert.Equal(new[] { "foo" }, target.SelectedItems);
- }
- [Fact]
- public void Preserves_Initial_SelectedItems_When_Bound()
- {
- // Issue #4272 (there are two issues there, this addresses the second one).
- var vm = new SelectionViewModel
- {
- Items = { "foo", "bar", "baz" },
- SelectedItems = { "bar" },
- };
- var target = new ListBox
- {
- [!ListBox.ItemsSourceProperty] = new Binding("Items"),
- [!ListBox.SelectedItemsProperty] = new Binding("SelectedItems"),
- DataContext = vm,
- };
- Prepare(target);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal(new[] { 1 }, target.Selection.SelectedIndexes);
- Assert.Equal("bar", target.SelectedItem);
- Assert.Equal(new[] { "bar" }, target.SelectedItems);
- }
- [Fact]
- public void Preserves_SelectedItem_When_Items_Changed()
- {
- // Issue #4048
- using var app = Start();
- var target = new SelectingItemsControl
- {
- ItemsSource = new[] { "foo", "bar", "baz"},
- SelectedItem = "bar",
- };
- Prepare(target);
- Assert.Equal(1, target.SelectedIndex);
- Assert.Equal("bar", target.SelectedItem);
- target.ItemsSource = new[] { "qux", "foo", "bar" };
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal("bar", target.SelectedItem);
- }
- [Fact]
- public void Setting_SelectedItems_Raises_PropertyChanged()
- {
- using var app = Start();
- var target = new TestSelector
- {
- ItemsSource = new[] { "foo", "bar", "baz" },
- };
- var raised = 0;
- var newValue = new AvaloniaList<object>();
- Prepare(target);
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == ListBox.SelectedItemsProperty)
- {
- Assert.Null(e.OldValue);
- Assert.Same(newValue, e.NewValue);
- ++raised;
- }
- };
- target.SelectedItems = newValue;
- Assert.Equal(1, raised);
- }
- [Fact]
- public void Setting_Selection_Raises_SelectedItems_PropertyChanged()
- {
- using var app = Start();
- var target = new TestSelector
- {
- ItemsSource = new[] { "foo", "bar", "baz" },
- };
- var raised = 0;
- var oldValue = target.SelectedItems;
- Prepare(target);
- target.PropertyChanged += (s, e) =>
- {
- if (e.Property == ListBox.SelectedItemsProperty)
- {
- Assert.Same(oldValue, e.OldValue);
- Assert.Null(e.NewValue);
- ++raised;
- }
- };
- target.Selection = new SelectionModel<int>();
- Assert.Equal(1, raised);
- }
- [Fact]
- public void Handles_Removing_Last_Item_In_Two_Controls_With_Bound_SelectedIndex()
- {
- var items = new ObservableCollection<string> { "foo" };
- // Simulates problem with TabStrip and Carousel with bound SelectedIndex.
- var tabStrip = new TestSelector
- {
- ItemsSource = items,
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var carousel = new TestSelector
- {
- ItemsSource = items,
- [!Carousel.SelectedIndexProperty] = tabStrip[!TabStrip.SelectedIndexProperty],
- };
- var tabStripRaised = 0;
- var carouselRaised = 0;
- tabStrip.SelectionChanged += (s, e) =>
- {
- Assert.Equal(new[] { "foo" }, e.RemovedItems);
- Assert.Empty(e.AddedItems);
- ++tabStripRaised;
- };
- carousel.SelectionChanged += (s, e) =>
- {
- Assert.Equal(new[] { "foo" }, e.RemovedItems);
- Assert.Empty(e.AddedItems);
- ++carouselRaised;
- };
- items.RemoveAt(0);
- Assert.Equal(1, tabStripRaised);
- Assert.Equal(1, carouselRaised);
- }
- [Fact]
- public void Handles_Removing_Last_Item_In_Controls_With_Bound_SelectedItem()
- {
- var items = new ObservableCollection<string> { "foo" };
- // Simulates problem with TabStrip and Carousel with bound SelectedItem.
- var tabStrip = new TestSelector
- {
- ItemsSource = items,
- SelectionMode = SelectionMode.AlwaysSelected,
- };
- var carousel = new TestSelector
- {
- ItemsSource = items,
- [!Carousel.SelectedItemProperty] = tabStrip[!TabStrip.SelectedItemProperty],
- };
- var tabStripRaised = 0;
- var carouselRaised = 0;
- tabStrip.SelectionChanged += (s, e) =>
- {
- Assert.Equal(new[] { "foo" }, e.RemovedItems);
- Assert.Empty(e.AddedItems);
- ++tabStripRaised;
- };
- carousel.SelectionChanged += (s, e) =>
- {
- Assert.Equal(new[] { "foo" }, e.RemovedItems);
- Assert.Empty(e.AddedItems);
- ++carouselRaised;
- };
- items.RemoveAt(0);
- Assert.Equal(1, tabStripRaised);
- Assert.Equal(1, carouselRaised);
- }
- [Fact]
- public void Setting_IsTextSearchEnabled_Enables_Or_Disables_Text_Search()
- {
- var pti = Mock.Of<IDispatcherImpl>(x => x.CurrentThreadIsLoopThread == true);
-
- using (UnitTestApplication.Start(TestServices.StyledWindow.With(dispatcherImpl: pti)))
- {
- var items = new[]
- {
- new Item { [TextSearch.TextProperty] = "Foo" },
- new Item { [TextSearch.TextProperty] = "Bar" }
- };
- var target = new SelectingItemsControl
- {
- ItemsSource = items,
- Template = Template(),
- IsTextSearchEnabled = false
- };
- Prepare(target);
- target.RaiseEvent(new TextInputEventArgs
- {
- RoutedEvent = InputElement.TextInputEvent,
- Device = KeyboardDevice.Instance,
- Text = "Foo"
- });
- Assert.Null(target.SelectedItem);
- target.IsTextSearchEnabled = true;
- target.RaiseEvent(new TextInputEventArgs
- {
- RoutedEvent = InputElement.TextInputEvent,
- Device = KeyboardDevice.Instance,
- Text = "Foo"
- });
- Assert.Equal(items[0], target.SelectedItem);
- }
- }
- private static IDisposable Start()
- {
- return UnitTestApplication.Start(TestServices.StyledWindow);
- }
- private static void Prepare(SelectingItemsControl target)
- {
- var root = new TestRoot
- {
- Child = target,
- Width = 100,
- Height = 100,
- Styles =
- {
- new Style(x => x.Is<SelectingItemsControl>())
- {
- Setters =
- {
- new Setter(ListBox.TemplateProperty, Template()),
- },
- },
- },
- };
- root.LayoutManager.ExecuteInitialLayoutPass();
- }
- private static void Layout(Control c)
- {
- ((ILayoutRoot)c.GetVisualRoot()).LayoutManager.ExecuteLayoutPass();
- }
- private static FuncControlTemplate Template()
- {
- return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>
- new ItemsPresenter
- {
- Name = "itemsPresenter",
- [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
- }.RegisterInNameScope(scope));
- }
- private class Item : Control, ISelectable
- {
- public string Value { get; set; }
- public bool IsSelected { get; set; }
- }
- private class MasterViewModel : NotifyingBase
- {
- private ChildViewModel _child;
- public ChildViewModel Child
- {
- get { return _child; }
- set
- {
- _child = value;
- RaisePropertyChanged();
- }
- }
- }
- private class ChildViewModel : NotifyingBase
- {
- public IList<Item> Items { get; set; }
- public Item SelectedItem { get; set; }
- public int SelectedIndex { get; set; }
- }
- private class SelectionViewModel : NotifyingBase
- {
- private int _selectedIndex = -1;
- public SelectionViewModel()
- {
- Items = new ObservableCollection<string>();
- SelectedItems = new ObservableCollection<string>();
- }
- public int SelectedIndex
- {
- get => _selectedIndex;
- set
- {
- _selectedIndex = value;
- RaisePropertyChanged();
- }
- }
- public ObservableCollection<string> Items { get; }
- public ObservableCollection<string> SelectedItems { get; }
- }
- private class RootWithItems : TestRoot
- {
- public List<string> Items { get; set; } = new List<string>() { "a", "b", "c", "d", "e" };
- public string Selected { get; set; } = "b";
- }
- private class TestSelector : SelectingItemsControl
- {
- public TestSelector()
- {
-
- }
- public TestSelector(SelectionMode selectionMode)
- {
- SelectionMode = selectionMode;
- }
- public new ISelectionModel Selection
- {
- get => base.Selection;
- set => base.Selection = value;
- }
- public new IList SelectedItems
- {
- get => base.SelectedItems;
- set => base.SelectedItems = value;
- }
- public new SelectionMode SelectionMode
- {
- get => base.SelectionMode;
- set => base.SelectionMode = value;
- }
- public new bool MoveSelection(NavigationDirection direction, bool wrap)
- {
- return base.MoveSelection(direction, wrap);
- }
- }
- private class ResettingCollection : List<string>, INotifyCollectionChanged
- {
- public ResettingCollection(int itemCount)
- {
- AddRange(Enumerable.Range(0, itemCount).Select(x => $"Item{x}"));
- }
- public void Reset(IEnumerable<string> items)
- {
- Clear();
- AddRange(items);
- CollectionChanged?.Invoke(
- this,
- new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
- }
- public event NotifyCollectionChangedEventHandler CollectionChanged;
- }
- }
- }
|