Chuyển đổi ComboBox thành AutoCompleteBox bằng Bộ công cụ WPF
Tôi đang gặp một chút khó khăn khi chuyển đổi ComboBox "phức tạp" thành AutoCompleteBox phức tạp không kém. Mục tiêu của tôi là có thể chọn và đặt một Mặt hàng của ShoppingCart giống như một trong các Mặt hàng của danh sách. Đây là ba bước cần thực hiện để tái tạo tình huống của tôi (Tôi đang sử dụng Stylet và phương thức SetAndNotify () INPC của nó) :
Tạo hai đối tượng, một đối tượng chỉ có thuộc tính Name và đối tượng kia chỉ có đối tượng kia làm thuộc tính
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; } }khởi tạo và điền cả Danh sách mục và Cửa hàng mua sắm trong DataContext (vì chúng tôi đang sử dụng MVVM, đó là 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() }; }Tạo AutoCompleteBox, ComboBox và một TextBlock nhỏ bên trong View để kiểm tra tất cả:
<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>
Thay đổi Chế độ ràng buộc của SelectedItem của AutoCompleteBox thành TwoWay làm cho nó in " [ProjectName] .ItemModel ", có nghĩa là (tôi đoán?) Nó nhận ItemModels chứ không phải chuỗi, nhưng tôi dường như không thể làm cho nó hoạt động. Mọi sự giúp đỡ sẽ được đánh giá cao, cảm ơn và vui lòng chỉnh sửa bài đăng của tôi nếu có thể làm cho nó nhỏ hơn.
Trả lời
Sau rất nhiều cố gắng, cuối cùng tôi đã tìm ra thủ phạm:
INPC không được triển khai
ShoppingCartModel.Itemmặc dù cóPropertyChangedBasekế thừa (hoặc triển khai INPC hoặc loại bỏPropertyChangedBasecông việc kế thừa)public class ShoppingCartModel : PropertyChangedBase { private ItemModel _item; public ItemModel Item { get => _item; set => SetAndNotify(ref _item, value); } }AutoCompleteBox
SelectedItemphải cùng loạiItemsSourcevà cóTwoWayChế độBinding<toolkit:AutoCompleteBox ItemsSource="{Binding ItemsList}" ValueMemberPath="Name" SelectedItem="{Binding Path=ShoppingCart.Item, Mode=TwoWay}" ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"/>Và cuối cùng ... bí ẩn nhất là ComboBox! Chỉ đơn giản là ở đó nó sẽ gây rối
AutoCompleteBoxvà tôi không biết tại sao, chỉ cần nhận xét toàn bộ ComboBox là mọi thứ sẽ hoạt động. Nếu bạn biết lý do tại sao ComboBox phá vỡ ràng buộc của AutoCompleteBox, vui lòng trợ giúp.
Tuy nhiên, có một vấn đề khác, khi sử dụng AutoCompleteBox bên trong ListView, nhưng tốt hơn là bạn nên tạo một câu hỏi riêng cho vấn đề đó tại đây