Conversion d'une zone de liste déroulante en une zone de saisie semi-automatique à l'aide de la boîte à outils WPF
J'ai un peu de mal à réaliser la conversion d'une ComboBox "complexe" en une AutoCompleteBox tout aussi complexe. Mon objectif est de pouvoir sélectionner et définir l'article d'un panier d'achat comme l'un des articles d'une liste. Voici les trois étapes à suivre pour reproduire ma situation (j'utilise Stylet et sa méthode SetAndNotify () INPC) :
Créez deux objets, l'un n'ayant qu'une propriété Name et l'autre n'ayant que l'autre objet comme propriété
public class ItemModel : PropertyChangedBase { private string _name; public string Name { get => _name; set => SetAndNotify(ref _name, value); } } public class ShoppingCartModel : PropertyChangedBase { public ItemModel Item { get; set; } }
initialiser et remplir à la fois le ItemsList et le Shoppingcart dans le DataContext (puisque nous utilisons MVVM, c'est le ViewModel)
public ShoppingCartModel ShoppingCart { get; set; } public ObservableCollection<ItemModel> ItemsList { get; set; } public ShellViewModel() { ItemsList = new ObservableCollection<ItemModel>() { new ItemModel { Name = "T-shirt"}, new ItemModel { Name = "Jean"}, new ItemModel { Name = "Boots"}, new ItemModel { Name = "Hat"}, new ItemModel { Name = "Jacket"}, }; ShoppingCart = new ShoppingCartModel() { Item = new ItemModel() }; }
Créez l'AutoCompleteBox, ComboBox et un petit TextBlock à l'intérieur de la vue pour tout tester:
<Window [...] xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=DotNetProjects.Input.Toolkit"> <!-- Required Template to show the names of the Items in the ItemsList --> <Window.Resources> <DataTemplate x:Key="AutoCompleteBoxItemTemplate"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Background="Transparent"> <Label Content="{Binding Name}"/> </StackPanel> </DataTemplate> </Window.Resources> <StackPanel> <!-- AutoCompleteBox: can see the items list but selecting doesn't change ShoppingCart.Item.Name --> <Label Content="AutoCompleteBox with ShoppingCart.Item.Name as SelectedItem:"/> <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}" ValueMemberPath="Name" SelectedItem="{Binding Path=ShoppingCart.Item.Name}" ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/> <!-- ComboBox: can see the items list and selecting changes ShoppingCart.Item.Name value --> <Label Content="ComboBox with ShoppingCart.Item.Name as SelectedValue:"/> <ComboBox ItemsSource="{Binding ItemsList}" DisplayMemberPath="Name" SelectedValue="{Binding Path=ShoppingCart.Item.Name}" SelectedValuePath="Name" SelectedIndex="{Binding Path=ShoppingCart.Item}" /> <!-- TextBox: Typing "Jean" or "Jacket" updates the ComboBox, but not the AutoCompleteBox --> <Label Content="Value of ShoppingCart.Item.Name:"/> <TextBox Text="{Binding Path=ShoppingCart.Item.Name}"/> </StackPanel> </window>
Changer le mode de liaison de SelectedItem de l'AutoCompleteBox en TwoWay le fait imprimer " [ProjectName] .ItemModel " ce qui signifie (je suppose?) Qu'il obtient des ItemModels et non des chaînes, mais je n'arrive pas à le faire fonctionner. Toute aide sera appréciée, merci et n'hésitez pas à modifier mon message s'il est possible de le réduire.
Réponses
Après de nombreuses tentatives, j'ai finalement trouvé les coupables:
INPC non implémenté
ShoppingCartModel.Item
malgré l'PropertyChangedBase
héritage (implémentation d'INPC ou suppression duPropertyChangedBase
travail d'héritage)public class ShoppingCartModel : PropertyChangedBase { private ItemModel _item; public ItemModel Item { get => _item; set => SetAndNotify(ref _item, value); } }
Les AutoCompleteBox
SelectedItem
doivent être du même typeItemsSource
et avoir unTwoWay
modeBinding
<toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}" ValueMemberPath="Name" SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
Et enfin ... le plus mystérieux est le ComboBox! Simplement en étant là, ça dérange le
AutoCompleteBox
et je ne sais pas pourquoi, il suffit de commenter l'ensemble de la ComboBox pour que tout fonctionne. Si vous savez pourquoi le ComboBox rompt la liaison de l'AutoCompleteBox, n'hésitez pas à vous aider.
Il y a un autre problème cependant, lors de l'utilisation d'un AutoCompleteBox dans un ListView, mais il est préférable de créer une question distincte pour ce problème ici