Conversione di un ComboBox in un AutoCompleteBox utilizzando WPF Toolkit

Aug 17 2020

Sto avendo un po 'di problemi per ottenere la conversione di un ComboBox "complesso" in un AutoCompleteBox altrettanto complesso. Il mio obiettivo è essere in grado di selezionare e impostare un articolo di un carrello in modo che sia come uno degli elementi di un elenco. Ecco i tre passaggi da eseguire per riprodurre la mia situazione (sto usando Stylet e il suo metodo INPC SetAndNotify ()) :

  1. Crea due oggetti, uno con solo una proprietà Name e l'altro con solo l'altro oggetto come proprietà

    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; }
    }
    
  2. inizializza e popola sia ItemList che Shoppingcart nel DataContext (dato che stiamo usando MVVM, è 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() };
    }
    
  3. Crea la casella di completamento automatico, la casella combinata e un piccolo blocco di testo all'interno della vista per testare tutto:

    <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>
    

La modifica della modalità di associazione di SelectedItem di AutoCompleteBox in TwoWay fa stampare " [ProjectName] .ItemModel " che significa (immagino?) Sta ottenendo ItemModels e non stringhe, ma non riesco a farlo funzionare. Qualsiasi aiuto sarà apprezzato, grazie e sentiti libero di modificare il mio post se è possibile rimpicciolirlo.

Risposte

Saliom Aug 21 2020 at 21:07

Dopo molti tentativi, ho finalmente trovato i colpevoli:

  • INPC non implementato ShoppingCartModel.Itemnonostante l' PropertyChangedBaseereditarietà (implementando INPC o rimuovendo il PropertyChangedBaselavoro di eredità)

    public class ShoppingCartModel : PropertyChangedBase
    {
        private ItemModel _item;
        public ItemModel Item
        {
            get => _item;
            set => SetAndNotify(ref _item, value);
        }
    }
    
  • Gli AutoCompleteBox SelectedItemdevono essere dello stesso tipo ItemsSourcee avere un TwoWayModeBinding

    <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}"
                             ValueMemberPath="Name"
                             SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" 
                             ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
    
  • E infine ... il più misterioso è il ComboBox! Semplicemente stando lì si confonde con il AutoCompleteBoxe non ho idea del perché, solo commentare l'intero ComboBox fa funzionare tutto. Se sai perché il ComboBox interrompe l'associazione di AutoCompleteBox, sentiti libero di aiutarti.

C'è un altro problema, però, quando si utilizza un AutoCompleteBox all'interno di un ListView, ma è meglio creare una domanda separata per quel problema qui