使用 WPF 工具包将 ComboBox 转换为 AutoCompleteBox
Converting a ComboBox to an AutoCompleteBox using the WPF Toolkit
我在将“复杂的”ComboBox 转换为同样复杂的 AutoCompleteBox 时遇到了一些麻烦。我的目标是能够 select 并将 ShoppingCart 的项目设置为类似于列表的项目之一。这是重现我的情况的三个步骤 (我正在使用 Stylet 及其 SetAndNotify() INPC 方法):
创建两个对象,一个只有名称 属性,另一个只有另一个对象作为 属性
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; }
}
在 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() };
}
在视图中创建 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 而不是字符串,但我似乎无法让它工作。任何帮助将不胜感激,谢谢并随时编辑我的 post 如果可以缩小它。
经过多次尝试,终于找到了罪魁祸首:
尽管有 PropertyChangedBase
继承 ShoppingCartModel.Item
INPC 未实现(要么实现 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 绑定的原因,请随时提供帮助。
虽然在 ListView 中使用自动完成框时还有另一个问题,但是
我在将“复杂的”ComboBox 转换为同样复杂的 AutoCompleteBox 时遇到了一些麻烦。我的目标是能够 select 并将 ShoppingCart 的项目设置为类似于列表的项目之一。这是重现我的情况的三个步骤 (我正在使用 Stylet 及其 SetAndNotify() INPC 方法):
创建两个对象,一个只有名称 属性,另一个只有另一个对象作为 属性
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; } }
在 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() }; }
在视图中创建 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 而不是字符串,但我似乎无法让它工作。任何帮助将不胜感激,谢谢并随时编辑我的 post 如果可以缩小它。
经过多次尝试,终于找到了罪魁祸首:
尽管有
PropertyChangedBase
继承ShoppingCartModel.Item
INPC 未实现(要么实现 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 绑定的原因,请随时提供帮助。
虽然在 ListView 中使用自动完成框时还有另一个问题,但是