使用WPF工具包将ComboBox转换为AutoCompleteBox

问题描述

在将“复杂”的ComboBox转换为同样复杂的autocompletebox时遇到了麻烦。我的目标是能够选择和设置ShoppingCart的商品,使其类似于列表中的商品之一。这是重现我的情况的三个步骤(我正在使用Stylet及其SetAndNotify()INPC方法

  1. 创建两个对象,一个仅具有Name属性,而另一个仅具有另一个对象

    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 中初始化并填充ItemsList和Shoppingcart(因为我们使用的是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. 在视图内创建autocompletebox,ComboBox一个小的TextBlock进行测试:

    <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的SelectedItem的绑定模式更改为TwoWay,使它打印“ [ProjectName] .Itemmodel ”,这意味着(我猜是?)它正在获取Itemmodels,而不是字符串,但我似乎无法使其正常运行。任何帮助将不胜感激,谢谢,如果可能的话,可以随时编辑我的帖子。

解决方法

经过多次尝试,我终于找到了罪魁祸首:

    尽管有ShoppingCartModel.Item继承(实现INPC或删除了PropertyChangedBase继承工作),但
  • INPC仍未在PropertyChangedBase中实现

public class ShoppingCartModel : PropertyChangedBase
{
    private ItemModel _item;
    public ItemModel Item
    {
        get => _item;
        set => SetAndNotify(ref _item,value);
    }
}
  • AutoCompleteBox的SelectedItem必须与ItemsSource类型相同,并且具有TwoWay模式Binding

    <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}"
                             ValueMemberPath="Name"
                             SelectedItem="{Binding Path=ShoppingCart.Item,Mode=TwoWay}" 
                             ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
    
  • 最后……最神秘的一个是ComboBox!仅仅在那里,它就与AutoCompleteBox混为一谈,我不知道为什么,仅评论整个ComboBox就能使其全部正常工作。如果您知道为什么ComboBox破坏了AutoCompleteBox的绑定,请随时提供帮助。

    exponential-backoff

  • 在ListView中使用AutoCompleteBox时,还有一个问题,但是AutoCompleteBox working