Bir ComboBox'ı WPF Toolkit kullanarak Otomatik Tamamlama Kutusu'na dönüştürme

Aug 17 2020

"Karmaşık" bir ComboBox'ı eşit derecede karmaşık bir AutoCompleteBox'a dönüştürmek için biraz sorun yaşıyorum. Amacım, bir Alışveriş Arabasının Öğesini bir listenin Öğelerinden biri gibi seçip ayarlayabilmek. Durumumu yeniden oluşturmak için atılacak üç adım (Stylet ve SetAndNotify () INPC yöntemini kullanıyorum) :

  1. Biri yalnızca bir Name özelliğine sahip olan ve diğeri yalnızca diğer nesnenin bir özellik olarak bulunduğu iki nesne oluşturun

    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. DataContext'te hem ItemsList hem de Shoppingcart'ı başlat ve doldur (MVVM kullandığımız için bu 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. AutoCompleteBox, ComboBox ve tümünü test etmek için View içinde küçük bir TextBlock oluşturun:

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

AutoCompleteBox'un SelectedItem'inin Bağlama Modunu TwoWay olarak değiştirmek, onu " [ProjectName] .ItemModel " yazdırmasını sağlar, bu da (sanırım?) ItemModel'ları alıyor, dizeleri değil, ancak çalışmasını sağlayamıyorum. Herhangi bir yardım takdir edilecektir, teşekkürler ve eğer onu küçültmek mümkünse gönderimi düzenlemekten çekinmeyin.

Yanıtlar

Saliom Aug 21 2020 at 21:07

Birçok denemeden sonra sonunda suçluları buldum:

  • INPC uygulanmadı ShoppingCartModel.Itemrağmen PropertyChangedBasemiras (ya INPC uygulayan veya kaldırma PropertyChangedBasemiras çalışmalarını)

    public class ShoppingCartModel : PropertyChangedBase
    {
        private ItemModel _item;
        public ItemModel Item
        {
            get => _item;
            set => SetAndNotify(ref _item, value);
        }
    }
    
  • AutoCompleteBox'lar SelectedItemaynı türde olmalı ItemsSourceve bir TwoWayMod'a sahip olmalıdırBinding

    <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}"
                             ValueMemberPath="Name"
                             SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" 
                             ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
    
  • Ve son olarak ... en gizemli olanı ComboBox'tır! Basitçe orada olmakla uğraşıyor AutoCompleteBoxve neden hiçbir fikrim yok, sadece tüm ComboBox'a yorum yapmak her şeyin çalışmasını sağlıyor. ComboBox'un AutoCompleteBox'ın bağlantısını neden bozduğunu biliyorsanız, yardım etmekten çekinmeyin.

ListView içinde AutoCompleteBox kullanırken başka bir sorun daha var , ancak burada bu sorun için ayrı bir soru oluşturmak daha iyidir