有没有办法在 WPF 中对 ComboBox 的下拉列表进行排序?
Is there a way to sort the drop-.down list of a ComboBox in WPF?
我目前正在开发一个 WPF 应用程序,该应用程序的任务是管理比萨饼店送货上门的订单。拥有一个基于 phone 数字的工作数据库至关重要。调度员在 phone 号码中写入 him/her 客户的所有详细信息(姓名、地址、评论等)。
我想要一个 ComboBox,您可以在其中键入要搜索的数字。我有点让它工作,但我错过了一个我不知道如何解决的重要部分。事情是这样的。
我想让 ComboBox 像这样工作:您开始在 ComboBox 的 .Text 字段中输入数字,在 return 将 select 最匹配的 phone 数字,并对 ObservableColletion 下拉列表中的所有其他紧密匹配的 phone 数字进行排序( 图 1)。按照标准,ComboBox 下拉列表不是 filtering/sorting 它获得的源“列表”,它只会根据您键入的内容更改 .Text 属性 中的 selection。
图1
Current state of development of the ComboBox
在匈牙利,我们有以下 phone 号码模式:
[提供商[xx]] [卡ID[xxx-xxxx]] ->9 nums
即:20 - 324-7784
(20- Telenor、70-沃达丰等...)
我有以下 XAML 组合框。
<ComboBox x:Name="PhoneBox" materialDesign:HintAssist.Hint="Keresés" IsEditable="True"
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
Width="1000" Height="50" HorizontalAlignment="Left" VerticalAlignment="Center"
Margin="150,0,0,0" FontSize="20"
ItemsSource="{Binding SELECTEDPHONES, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:Order_placeCustomerData_panel}},
UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SELECTED, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:Order_placeCustomerData_panel}}}"/>
这里是 ComboBox 的当前后端。
我从头开始计算我检查过的完整 phone 数字的哪个索引,因此我可以跟踪哪个部分是新输入的部分。首先,我收集了所有满足当前条件的 phone 个数字,以及所有不满足当前条件的 phone 个数字。然后我用一个坏的交换一个好的。在此过程中,我根据他们的位置标记他们。如果一个好人的位置小于 GoodOnes.Count,它就会进入标志列表。为了完成这个过程,我将每个标记的项目与一个已经放置好的项目从顶部开始交换(好的项目的最高索引)。
这样做的原因是,当你交换 PHONES[2](坏的) 与 PHONES[5](好的)并且你有 8 个好的,在这个过程之后,PHONES[5] 将是一个带有错误数字的“洞”文件。好-好-好-好-坏-好-好-好。)
//Propeties and stuff
private string[] typed = new string[9];
private int typedIndex = 0;
private bool isReevaluating = false;
private ObservableCollection<string> _selectedPhones;
private string _selected;
public ObservableCollection<string> SELECTEDPHONES
{
get { return _selectedPhones; }
set
{
_selectedPhones = value;
}
}
public string SELECTED
{
get { return _selected; }
set
{
_selected = value;
OnPropertyChanged("SELECTED");
}
}
//Function for Reeavluating the drop-down list
private void ReevaluatePhones()
{
if (SELECTED == null)
{
return;
}
isReevaluating = true;
typed[typedIndex] = SELECTED[typedIndex].ToString();
string toExamine;
List<int> Satisfies = new List<int>();
List<int> notSatisfies = new List<int>();
for (int j = 0; j < PHONES.Count; j++)
{
toExamine = PHONES[j].ToString();
if (toExamine[typedIndex].ToString() == typed[typedIndex].ToString())
{
Satisfies.Add(j);
}
else
{
notSatisfies.Add(j);
}
}
List<int> flagSatisfies = new List<int>();
int flagLast = 0;
for (int i = 0; i < Satisfies.Count; i++)
{
if (Satisfies[i] < Satisfies.Count)
{
flagSatisfies.Add(Satisfies[i]);
}
string temp = PHONES[notSatisfies[i]];
PHONES[notSatisfies[i]] = PHONES[Satisfies[i]];
PHONES[Satisfies[i]] = temp;
flagLast = notSatisfies[i];
}
for (int i = 0; i < flagSatisfies.Count; i++)
{
string temp = PHONES[flagSatisfies[i]];
PHONES[flagSatisfies[i]] = PHONES[flagLast];
PHONES[flagLast] = temp;
flagLast--;
}
isReevaluating = false;
}
INotifyPropertyChanged接口只是基本实现,不包含任何异常,只是ComboBox的selected [=74=时事件的调用顺序] 变化。
上面的代码工作正常,但是当您错误输入 phone 数字并从文本字段中删除一些字符时,我不会收到有关更改的通知,只有在您输入时才会收到,而不会在删除时收到。
就我在 MS 文档上读到的而言,ComboBox 在值中没有 TYPED 的可访问字段,只有 selected 值是整个 [=61] =] 号。我无法基于此进行排序,因为我没有任何基本点可以与之进行比较。
总结一下。
我想根据 ComboBox.Text 字段中输入的值对下拉列表(这是一个 ObservableColelction)进行排序。为了让我上面的解决方案起作用,我需要在 .Text 的值被部分或全部删除时得到通知。我乐于接受任何类型的指导、提示和想法。
非常感谢:)
我建议您使用 CollectionViewSource https://docs.microsoft.com/en-us/dotnet/api/system.windows.data.collectionviewsource?view=netframework-4.8.
此 class 的实例在 window 资源中声明。
来源 属性 包含 link 到您的 collection。
属性 Filter - 代码隐藏中的过滤方法 Window.
属性 IsLiveFilteringRequested 和 IsLiveSortingRequested = true 用于实时过滤和排序。
在 LiveFilteringProperties - 添加您要过滤的属性。
在 SortDescriptions - 排序条件。
当 ComboBox.Text 更改时,禁用并 re-enable IsLiveFilteringRequested 进行新的过滤。
ComboBox.ItemsSource 指向在资源中创建的 CollectionViewSource 实例。
我目前正在开发一个 WPF 应用程序,该应用程序的任务是管理比萨饼店送货上门的订单。拥有一个基于 phone 数字的工作数据库至关重要。调度员在 phone 号码中写入 him/her 客户的所有详细信息(姓名、地址、评论等)。
我想要一个 ComboBox,您可以在其中键入要搜索的数字。我有点让它工作,但我错过了一个我不知道如何解决的重要部分。事情是这样的。
我想让 ComboBox 像这样工作:您开始在 ComboBox 的 .Text 字段中输入数字,在 return 将 select 最匹配的 phone 数字,并对 ObservableColletion 下拉列表中的所有其他紧密匹配的 phone 数字进行排序( 图 1)。按照标准,ComboBox 下拉列表不是 filtering/sorting 它获得的源“列表”,它只会根据您键入的内容更改 .Text 属性 中的 selection。
图1 Current state of development of the ComboBox
在匈牙利,我们有以下 phone 号码模式:
[提供商[xx]] [卡ID[xxx-xxxx]] ->9 nums
即:20 - 324-7784
(20- Telenor、70-沃达丰等...)
我有以下 XAML 组合框。
<ComboBox x:Name="PhoneBox" materialDesign:HintAssist.Hint="Keresés" IsEditable="True"
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
Width="1000" Height="50" HorizontalAlignment="Left" VerticalAlignment="Center"
Margin="150,0,0,0" FontSize="20"
ItemsSource="{Binding SELECTEDPHONES, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:Order_placeCustomerData_panel}},
UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SELECTED, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:Order_placeCustomerData_panel}}}"/>
这里是 ComboBox 的当前后端。
我从头开始计算我检查过的完整 phone 数字的哪个索引,因此我可以跟踪哪个部分是新输入的部分。首先,我收集了所有满足当前条件的 phone 个数字,以及所有不满足当前条件的 phone 个数字。然后我用一个坏的交换一个好的。在此过程中,我根据他们的位置标记他们。如果一个好人的位置小于 GoodOnes.Count,它就会进入标志列表。为了完成这个过程,我将每个标记的项目与一个已经放置好的项目从顶部开始交换(好的项目的最高索引)。
这样做的原因是,当你交换 PHONES[2](坏的) 与 PHONES[5](好的)并且你有 8 个好的,在这个过程之后,PHONES[5] 将是一个带有错误数字的“洞”文件。好-好-好-好-坏-好-好-好。)
//Propeties and stuff
private string[] typed = new string[9];
private int typedIndex = 0;
private bool isReevaluating = false;
private ObservableCollection<string> _selectedPhones;
private string _selected;
public ObservableCollection<string> SELECTEDPHONES
{
get { return _selectedPhones; }
set
{
_selectedPhones = value;
}
}
public string SELECTED
{
get { return _selected; }
set
{
_selected = value;
OnPropertyChanged("SELECTED");
}
}
//Function for Reeavluating the drop-down list
private void ReevaluatePhones()
{
if (SELECTED == null)
{
return;
}
isReevaluating = true;
typed[typedIndex] = SELECTED[typedIndex].ToString();
string toExamine;
List<int> Satisfies = new List<int>();
List<int> notSatisfies = new List<int>();
for (int j = 0; j < PHONES.Count; j++)
{
toExamine = PHONES[j].ToString();
if (toExamine[typedIndex].ToString() == typed[typedIndex].ToString())
{
Satisfies.Add(j);
}
else
{
notSatisfies.Add(j);
}
}
List<int> flagSatisfies = new List<int>();
int flagLast = 0;
for (int i = 0; i < Satisfies.Count; i++)
{
if (Satisfies[i] < Satisfies.Count)
{
flagSatisfies.Add(Satisfies[i]);
}
string temp = PHONES[notSatisfies[i]];
PHONES[notSatisfies[i]] = PHONES[Satisfies[i]];
PHONES[Satisfies[i]] = temp;
flagLast = notSatisfies[i];
}
for (int i = 0; i < flagSatisfies.Count; i++)
{
string temp = PHONES[flagSatisfies[i]];
PHONES[flagSatisfies[i]] = PHONES[flagLast];
PHONES[flagLast] = temp;
flagLast--;
}
isReevaluating = false;
}
INotifyPropertyChanged接口只是基本实现,不包含任何异常,只是ComboBox的selected [=74=时事件的调用顺序] 变化。
上面的代码工作正常,但是当您错误输入 phone 数字并从文本字段中删除一些字符时,我不会收到有关更改的通知,只有在您输入时才会收到,而不会在删除时收到。
就我在 MS 文档上读到的而言,ComboBox 在值中没有 TYPED 的可访问字段,只有 selected 值是整个 [=61] =] 号。我无法基于此进行排序,因为我没有任何基本点可以与之进行比较。
总结一下。
我想根据 ComboBox.Text 字段中输入的值对下拉列表(这是一个 ObservableColelction)进行排序。为了让我上面的解决方案起作用,我需要在 .Text 的值被部分或全部删除时得到通知。我乐于接受任何类型的指导、提示和想法。
非常感谢:)
我建议您使用 CollectionViewSource https://docs.microsoft.com/en-us/dotnet/api/system.windows.data.collectionviewsource?view=netframework-4.8.
此 class 的实例在 window 资源中声明。
来源 属性 包含 link 到您的 collection。
属性 Filter - 代码隐藏中的过滤方法 Window.
属性 IsLiveFilteringRequested 和 IsLiveSortingRequested = true 用于实时过滤和排序。
在 LiveFilteringProperties - 添加您要过滤的属性。
在 SortDescriptions - 排序条件。
当 ComboBox.Text 更改时,禁用并 re-enable IsLiveFilteringRequested 进行新的过滤。
ComboBox.ItemsSource 指向在资源中创建的 CollectionViewSource 实例。