WPF Toolkit을 사용하여 ComboBox를 AutoCompleteBox로 변환

Aug 17 2020

"복잡한"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 및 View 내부에 작은 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가의 결합 모드를 변경하면 "그것을 인쇄 할 수 있습니다 [프로젝트 이름] .ItemModel "어떤 수단 (같아요?) 가 ItemModels가 아닌 문자열을지고있어,하지만 난 그것을 작동 할 수없는 것. 어떤 도움을 주시면 감사하겠습니다. 게시물을 작게 만들 수 있다면 자유롭게 편집하십시오.

답변

Saliom Aug 21 2020 at 21:07

많은 시도 끝에 마침내 범인을 찾았습니다.

  • 상속 ShoppingCartModel.Item에도 불구하고 INPC가 구현되지 않음 (INPC 구현 또는 상속 작업 제거 )PropertyChangedBasePropertyChangedBase

    public class ShoppingCartModel : PropertyChangedBase
    {
        private ItemModel _item;
        public ItemModel Item
        {
            get => _item;
            set => SetAndNotify(ref _item, value);
        }
    }
    
  • AutoCompleteBox SelectedItem는 동일한 유형이어야하며 모드 ItemsSource가 있어야합니다.TwoWayBinding

    <toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}"
                             ValueMemberPath="Name"
                             SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" 
                             ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>
    
  • 그리고 마지막으로 ... 가장 신비로운 것은 ComboBox입니다! 단순히 거기에 있으면서 엉망이되고 AutoCompleteBox이유를 모르겠습니다. 전체 ComboBox에 주석을 달면 모든 것이 작동합니다. ComboBox가 AutoCompleteBox의 바인딩을 깨뜨리는 이유를 알고 있다면 언제든지 도와주세요.

그러나 ListView 내에서 AutoCompleteBox를 사용할 때 또 다른 문제가 있지만 여기에서 해당 문제에 대한 별도의 질문을 만드는 것이 좋습니다.