Konvertieren einer ComboBox in eine AutoCompleteBox mit dem WPF Toolkit

Aug 17 2020

Ich habe einige Probleme, die Konvertierung einer "komplexen" ComboBox in eine ebenso komplexe AutoCompleteBox zu erreichen. Mein Ziel ist es, einen ShoppingCart-Artikel so auswählen und einstellen zu können, dass er einem der Artikel einer Liste entspricht. Hier sind die drei Schritte, die Sie ausführen müssen , um meine Situation zu reproduzieren (ich verwende Stylet und seine INPC-Methode SetAndNotify ()) :

  1. Erstellen Sie zwei Objekte, von denen eines nur eine Name-Eigenschaft und das andere nur das andere Objekt als Eigenschaft hat

    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. Initialisieren und füllen Sie sowohl die ItemsList als auch den Shoppingcart im DataContext (da wir MVVM verwenden, ist es das 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. Erstellen Sie die AutoCompleteBox, ComboBox und einen kleinen TextBlock in der Ansicht, um alles zu testen:

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

Wenn Sie den Bindungsmodus des SelectedItem der AutoCompleteBox in TwoWay ändern, wird " [ProjectName] .ItemModel " ausgegeben, was bedeutet (ich denke?) , Dass ItemModels und keine Zeichenfolgen abgerufen werden, aber ich kann nicht scheinen, dass es funktioniert. Jede Hilfe wird geschätzt, danke und zögern Sie nicht, meinen Beitrag zu bearbeiten, wenn es möglich ist, ihn kleiner zu machen.

Antworten

Saliom Aug 21 2020 at 21:07

Nach vielen Versuchen fand ich endlich die Schuldigen:

  • INPC ShoppingCartModel.Itemtrotz PropertyChangedBaseVererbung nicht implementiert (entweder INPC implementieren oder PropertyChangedBaseVererbungsarbeit entfernen )

    public class ShoppingCartModel : PropertyChangedBase
    {
        private ItemModel _item;
        public ItemModel Item
        {
            get => _item;
            set => SetAndNotify(ref _item, value);
        }
    }
    
  • AutoCompleteBoxen SelectedItemmüssen vom gleichen Typ sein ItemsSourceund einen TwoWayModus habenBinding

    <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}"
                             ValueMemberPath="Name"
                             SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" 
                             ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
    
  • Und schließlich ... das Geheimnisvollste ist die ComboBox! Einfach AutoCompleteBoxda zu sein, bringt es mit dem durcheinander und ich habe keine Ahnung warum, wenn ich nur die ganze ComboBox kommentiere, funktioniert alles. Wenn Sie wissen, warum die ComboBox die Bindung der AutoCompleteBox unterbricht, können Sie uns gerne weiterhelfen.

Es gibt zwar ein anderes Problem, wenn Sie eine AutoCompleteBox in einer ListView verwenden, aber es ist besser, hier eine separate Frage für dieses Problem zu erstellen