1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656 |
- 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.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.Styling;
- using Avalonia.Threading;
- using Avalonia.UnitTests;
- using Avalonia.VisualTree;
- using Moq;
- using Xunit;
- namespace Avalonia.Controls.UnitTests.Primitives
- {
- public partial class SelectingItemsControlTests : ScopedTestBase
- {
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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()
- {
- using var app = Start();
- var items = new ObservableCollection<string> { "foo", "bar" };
- 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);
- }
- [Fact]
- public void Moving_Selected_Container_Should_Not_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);
- var receivedArgs = new List<SelectionChangedEventArgs>();
- target.SelectionChanged += (_, args) => receivedArgs.Add(args);
- var moved = items[1];
- items.Move(1, 0);
- // Because the moved container is still marked as selected on the insert part of the
- // move, it will remain selected.
- Assert.Same(moved, target.SelectedItem);
- Assert.Equal(0, target.SelectedIndex);
- Assert.NotNull(receivedArgs);
- Assert.Equal(2, receivedArgs.Count);
- Assert.Equal(new[] { moved }, receivedArgs[0].RemovedItems);
- Assert.Equal(new[] { moved }, receivedArgs[1].AddedItems);
- Assert.True(items[0].IsSelected);
- Assert.False(items[1].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 TabOnceActiveElement_Should_Be_Initialized_With_SelectedItem()
- {
- using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz " },
- SelectedIndex = 1,
- };
- Prepare(target);
- var container = target.ContainerFromIndex(1)!;
- Assert.Same(container, KeyboardNavigation.GetTabOnceActiveElement(target));
- }
- }
- [Fact]
- public void Setting_SelectedItem_With_Pointer_Should_Set_TabOnceActiveElement()
- {
- using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz " },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
- Prepare(target);
- var container = target.ContainerFromIndex(1)!;
- _helper.Down(container);
- var panel = target.Presenter.Panel;
- Assert.Same(container, KeyboardNavigation.GetTabOnceActiveElement(target));
- }
- }
- [Fact]
- public void Removing_SelectedItem_Should_Clear_TabOnceActiveElement()
- {
- using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
- {
- var items = new ObservableCollection<string>(new[] { "Foo", "Bar", "Baz " });
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = items,
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
- 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(TestServices.MockPlatformRenderInterface))
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
- 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(TestServices.MockPlatformRenderInterface))
- {
- var target = new ListBox
- {
- Template = Template(),
- ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
- };
- AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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;
- Threading.Dispatcher.UIThread.RunJobs();
- Assert.True(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Causes_Scroll_To_Initial_SelectedItem()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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);
- Threading.Dispatcher.UIThread.RunJobs();
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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;
- Threading.Dispatcher.UIThread.RunJobs();
- Assert.True(raised);
- }
- [Fact]
- public void AutoScrollToSelectedItem_Doesnt_Scroll_If_Reattached_To_Visual_Tree_With_No_Selection_Change()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- 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;
- Threading.Dispatcher.UIThread.RunJobs();
- Assert.False(raised);
- target.AutoScrollToSelectedItem = true;
- Threading.Dispatcher.UIThread.RunJobs();
- Assert.True(raised);
- }
- [Fact]
- public void Can_Set_Both_SelectedItem_And_SelectedItems_During_Initialization()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // 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()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // 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,
- Text = "Foo"
- });
- Assert.Null(target.SelectedItem);
- target.IsTextSearchEnabled = true;
- target.RaiseEvent(new TextInputEventArgs
- {
- RoutedEvent = InputElement.TextInputEvent,
- Text = "Foo"
- });
- Assert.Equal(items[0], target.SelectedItem);
- }
- }
- [Fact]
- public void Does_Not_Write_To_Bound_SelectedItem_When_DataContext_Changes()
- {
- // Issue #9438.
- var vm1 = new SelectionViewModel();
- vm1.Items.Add("foo");
- vm1.Items.Add("bar");
- vm1.SelectedItem = "bar";
- var vm2 = new SelectionViewModel();
- vm2.Items.Add("foo");
- vm2.Items.Add("bar");
- vm2.SelectedItem = "bar";
- var target = new SelectingItemsControl
- {
- DataContext = vm1,
- [!ItemsControl.ItemsSourceProperty] = new Binding("Items"),
- [!SelectingItemsControl.SelectedItemProperty] = new Binding("SelectedItem"),
- Template = Template(),
- };
- Assert.Equal("bar", target.SelectedItem);
- Assert.Equal(1, target.SelectedIndex);
- var selectedItemChangedRaised = 0;
- vm2.PropertyChanged += (s, e) =>
- {
- if (e.PropertyName == nameof(vm2.SelectedItem))
- {
- ++selectedItemChangedRaised;
- }
- };
- target.DataContext = vm2;
- Assert.Equal(0, selectedItemChangedRaised);
- }
-
- [Fact]
- public void Should_First_Raise_Property_Changed_Notification_Then_Fire_Selection_Changed_Event()
- {
- using var _ = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
- // Issue #11006
- var items = new ObservableCollection<string>();
-
- var vm = new SelectionViewModel
- {
- SelectedItem = "" ,
- };
-
- var theListBox = new ListBox
- {
- DataContext = vm,
- Template = Template(),
- ItemsSource = items,
- SelectionMode = SelectionMode.AlwaysSelected,
- [!ListBox.SelectedItemProperty] = new Binding("SelectedItem"),
- };
-
- var target = new TextBox
- {
- Text = "",
- };
- Prepare(theListBox);
-
- items.Add("Default");
- items.Add("First");
- items.Add("Second");
- items.Add("Third");
-
- theListBox.SelectionChanged += (s, e) =>
- {
- target.Text = (string)vm.SelectedItem;
- };
-
- theListBox.SelectedIndex = 1;
- Assert.Equal("First", target.Text);
- theListBox.SelectedIndex = 2;
- Assert.Equal("Second", target.Text);
- theListBox.SelectedIndex = 3;
- Assert.Equal("Third", target.Text);
- }
- [Theory]
- [MemberData(nameof(GetSelectionFieldPermutationParameters))]
- public void SelectedItem_And_Selection_Properties_Work_In_Any_Order_When_Initializing(SelectionField[] fields)
- => TestSelectionFields(vm => vm.SelectedItem = vm.Items[2], fields);
- [Theory]
- [MemberData(nameof(GetSelectionFieldPermutationParameters))]
- public void SelectedIndex_And_Selection_Properties_Work_In_Any_Order_When_Initializing(SelectionField[] fields)
- => TestSelectionFields(vm => vm.SelectedIndex = 2, fields);
- [Theory]
- [MemberData(nameof(GetSelectionFieldPermutationParameters))]
- public void SelectedValue_And_Selection_Properties_Work_In_Any_Order_When_Initializing(SelectionField[] fields)
- => TestSelectionFields(vm => vm.SelectedValue = 12, fields);
- private void TestSelectionFields(Action<FullSelectionViewModel> setItem2, SelectionField[] fields)
- {
- using var _ = Start();
- var vm = new FullSelectionViewModel
- {
- Items =
- {
- new ItemModel { Id = 10, Name = "Item0" },
- new ItemModel { Id = 11, Name = "Item1" },
- new ItemModel { Id = 12, Name = "Item2" },
- new ItemModel { Id = 13, Name = "Item3" }
- }
- };
- setItem2(vm);
- var root = new TestRoot
- {
- Width = 100,
- Height = 100
- };
- // Match the Begin/EndInit sequence emitted by the XAML compiler
- root.BeginInit();
- var target = new ListBox();
- target.BeginInit();
- root.Child = target;
- target.DataContext = vm;
- foreach (var field in fields)
- {
- switch (field)
- {
- case SelectionField.ItemsSource:
- target.Bind(ItemsControl.ItemsSourceProperty, new Binding(nameof(FullSelectionViewModel.Items)));
- break;
- case SelectionField.SelectedItem:
- target.Bind(SelectingItemsControl.SelectedItemProperty, new Binding(nameof(FullSelectionViewModel.SelectedItem)));
- break;
- case SelectionField.SelectedIndex:
- target.Bind(SelectingItemsControl.SelectedIndexProperty, new Binding(nameof(FullSelectionViewModel.SelectedIndex)));
- break;
- case SelectionField.SelectedValue:
- target.Bind(SelectingItemsControl.SelectedValueProperty, new Binding(nameof(FullSelectionViewModel.SelectedValue)));
- break;
- case SelectionField.SelectedValueBinding:
- target.SelectedValueBinding = new Binding(nameof(ItemModel.Id));
- break;
- default:
- throw new InvalidOperationException($"Unkown field {field}");
- }
- }
- target.EndInit();
- root.EndInit();
- Assert.Equal(vm.Items[2], target.SelectedItem);
- Assert.Equal(2, target.SelectedIndex);
- Assert.Equal(12, target.SelectedValue);
- Assert.Equal(vm.Items[2], vm.SelectedItem);
- Assert.Equal(2, vm.SelectedIndex);
- Assert.Equal(12, vm.SelectedValue);
- }
- [Fact]
- public void SelectedItem_Can_Access_Selection_DuringInit()
- {
- using var _ = Start();
- var target = new ListBox();
- target.BeginInit();
- var item = new ItemModel();
- target.Selection = new SelectionModel<ItemModel> {
- SelectedItem = item
- };
- Assert.Equal(item, target.SelectedItem);
- }
- [Fact]
- public void SelectedIndex_Can_Access_Selection_DuringInit()
- {
- using var _ = Start();
- var target = new ListBox();
- target.BeginInit();
- target.Selection = new SelectionModel<ItemModel> {
- SelectedIndex = 42
- };
- Assert.Equal(42, target.SelectedIndex);
- }
- [Fact]
- public void AnchorIndex_Can_Access_Selection_DuringInit()
- {
- using var _ = Start();
- var target = new ListBox();
- target.BeginInit();
- target.Selection = new SelectionModel<ItemModel> {
- AnchorIndex = 42
- };
- Assert.Equal(42, target.GetAnchorIndex());
- }
- 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));
- }
- public static IEnumerable<object[]> GetSelectionFieldPermutationParameters()
- => Enum.GetValues<SelectionField>().Permutations().Select(fields => new object[] { fields });
- private class Item : Control, ISelectable
- {
- public string Value { get; set; }
- public bool IsSelected
- {
- get => SelectingItemsControl.GetIsSelected(this);
- set => SelectingItemsControl.SetIsSelected(this, value);
- }
- }
- 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;
- private object _selectedItem;
- public SelectionViewModel()
- {
- Items = new ObservableCollection<string>();
- SelectedItems = new ObservableCollection<string>();
- }
- public int SelectedIndex
- {
- get => _selectedIndex;
- set
- {
- _selectedIndex = value;
- RaisePropertyChanged();
- }
- }
- public object SelectedItem
- {
- get => _selectedItem;
- set
- {
- _selectedItem = 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 new static readonly DirectProperty<SelectingItemsControl, IList> SelectedItemsProperty =
- SelectingItemsControl.SelectedItemsProperty;
- 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 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;
- }
- #nullable enable
- private sealed class FullSelectionViewModel : NotifyingBase
- {
- private ItemModel? _selectedItem;
- private int _selectedIndex = -1;
- private int? _selectedValue;
- public ObservableCollection<ItemModel> Items { get; } = new();
- public ItemModel? SelectedItem
- {
- get => _selectedItem;
- set => SetField(ref _selectedItem, value);
- }
- public int SelectedIndex
- {
- get => _selectedIndex;
- set => SetField(ref _selectedIndex, value);
- }
- public int? SelectedValue
- {
- get => _selectedValue;
- set => SetField(ref _selectedValue, value);
- }
- }
- private sealed class ItemModel : NotifyingBase
- {
- private int _id;
- private string? _name;
- public int Id
- {
- get => _id;
- set => SetField(ref _id, value);
- }
- public string? Name
- {
- get => _name;
- set => SetField(ref _name, value);
- }
- }
- public enum SelectionField
- {
- ItemsSource,
- SelectedItem,
- SelectedIndex,
- SelectedValue,
- SelectedValueBinding
- }
- }
- }
|