C# 命名动态生成的组合框项
我目前正在.NETCore3.1中从事一个WPF项目。在执行过程中,我必须将一些文件名读取到组合框中。我首先将它们添加到列表中。之后,我遍历该列表并将它们添加到组合框中 问题 因为它们只有在选择了另一个组合框中的项目时才可以访问,所以我需要禁用刚才添加的项目。因此,为了以后启用它们,我需要命名它们。但我不知道我们该怎么做 这是我的密码: 在foreach(ComboBoxItem currentItems in comboAircrafter.Items)行中,我得到一个异常:C# 命名动态生成的组合框项,c#,wpf,combobox,C#,Wpf,Combobox,我目前正在.NETCore3.1中从事一个WPF项目。在执行过程中,我必须将一些文件名读取到组合框中。我首先将它们添加到列表中。之后,我遍历该列表并将它们添加到组合框中 问题 因为它们只有在选择了另一个组合框中的项目时才可以访问,所以我需要禁用刚才添加的项目。因此,为了以后启用它们,我需要命名它们。但我不知道我们该怎么做 这是我的密码: 在foreach(ComboBoxItem currentItems in comboAircrafter.Items)行中,我得到一个异常: System.I
System.InvalidCastException:“无法将类型为“System.String”的对象强制转换为类型为“System.Windows.Controls.ComboBoxItem”。
我真的没什么主意了。我在谷歌上搜索了一整天,但什么也没找到
祝大家今天愉快 您正在尝试将
字符串
转换为ComboBoxItem
。用数据填充组合框时,添加的是字符串
,而不是组合框项
。因此,您应该在最后一个foreach
循环中使用String
foreach (string currentComboItems in comboAircraft.Items)
{
currentComboItems.Name = "comboAircraftItems" + currentComboItems;
}
另一种解决方案是将ComboBoxItem
添加到组合框中,而不是String
foreach (string currentListItem in aircraft)
{
ComboBoxItem item = new ComboBoxItem()
{
Content = currentListItem,
Name = "comboAircraftItems" + currentListItem
};
comboAircraft.Items.Add(item);
}
您正在尝试将
字符串
转换为ComboBoxItem
。用数据填充组合框时,添加的是字符串
,而不是组合框项
。因此,您应该在最后一个foreach
循环中使用String
foreach (string currentComboItems in comboAircraft.Items)
{
currentComboItems.Name = "comboAircraftItems" + currentComboItems;
}
另一种解决方案是将ComboBoxItem
添加到组合框中,而不是String
foreach (string currentListItem in aircraft)
{
ComboBoxItem item = new ComboBoxItem()
{
Content = currentListItem,
Name = "comboAircraftItems" + currentListItem
};
comboAircraft.Items.Add(item);
}
@t-kldw,当直接使用UI元素时,您的任务很难解决。 但是,如果您将数据和它们的表示分离,解决这个问题非常简单,因为MVVM中应该这样做 不幸的是,对于一个完整实现的示例,您所写的内容包含的细节很少。 我只能给出部分建议。 有必要为一个组合框中所需的数据创建一个额外的容器类。 此类必须具有INotifyPropertyChanged实现 要简化,请从主题中获取实现 为了让我能给出进一步的建议,你需要提供你任务的更多细节。 例如,我甚至不知道为什么需要currentComboItems.Name。。。。
我认为您显然做错了什么。@t-kldw,当直接使用UI元素时,您的任务很难解决。 但是,如果您将数据和它们的表示分离,解决这个问题非常简单,因为MVVM中应该这样做 不幸的是,对于一个完整实现的示例,您所写的内容包含的细节很少。 我只能给出部分建议。 有必要为一个组合框中所需的数据创建一个额外的容器类。 此类必须具有INotifyPropertyChanged实现 要简化,请从主题中获取实现 为了让我能给出进一步的建议,你需要提供你任务的更多细节。 例如,我甚至不知道为什么需要currentComboItems.Name。。。。
我认为您显然做错了什么。
ItemsControl.Items
只保存数据对象。为了呈现这些项目,每个项目都被包装到一个容器中,例如,ComboBoxItem
。这些UI容器由与当前ItemsControl
关联的itemsContainerGenerator
生成。ItemContainerGenerator
还负责跟踪数据项与其UI容器之间的映射。要获取项目的容器,请使用
ItemsControl.ItemContainerGenerator
:
DependencyObject itemContainer = ItemContainerGenerator.ContainerFromItem(item);
您的简化代码变成:
List<string> allAircrafts = Directory.EnumerateFiles(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
@"\ApplicationName\Aircraft\"),
"*.lxml",
SearchOption.TopDirectoryOnly)
.Select(Path.GetFileNameWithoutExtension)
.ToList();
comboAircraft.ItemsSource = allAircrafts;
foreach (string item in allAircrafts)
{
var itemContainer = comboAircraft.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
itemContainer.Name = "comboAircraftItems" + itemContainer.Content;
}
List allairrafts=Directory.enumerate文件(
路径。联合收割机(
GetFolderPath(Environment.SpecialFolder.ApplicationData),
@“\ApplicationName\Aircrafter\”,
“*.lxml”,
SearchOption.TopDirectoryOnly)
.Select(Path.GetFileNameWithoutExtension)
.ToList();
comboAircraft.ItemsSource=所有飞机;
foreach(allAircrafts中的字符串项)
{
var itemContainer=ComboAircrafter.ItemContainerGenerator.ContainerFromItem(item)作为ComboBoxItem;
itemContainer.Name=“comboAircraftItems”+itemContainer.Content;
}
但请注意,您选择的方法存在问题。当为itemscpntrol
启用UI虚拟化时,只有可见的项才会生成其容器。滚动查看器视口外的项目不会生成,并且不能由ItemContainerGenerator
返回由于默认情况下,
组合框
未启用UI虚拟化,因此只要不启用此性能优化功能,此功能仍可工作
最佳解决方案需要您为显示过滤项的组合框创建一个过滤源集合。这样,您就不会在控件中添加用户不感兴趣且无论如何都无法选择的项
创建一个类型为ObservableCollection
的集合,其中包含您命名的组合框的主要所选项目
将此集合设置为第二个筛选的组合框的项源
或者,创建原始源集合的CollectionViewSource
,并将其绑定到辅助组合框
<代码>ICollectionView
支持筛选。
正确的解决方案
使用这两种推荐的解决方案中的任何一种都不需要关心物品容器。这增加了灵活性并简化了代码。ItemsControl。Items
仅保存数据对象。为了呈现这些项目,每个项目都被包装到一个容器中,例如,ComboBoxItem
。这些UI容器由ItemContainerGenerator
生成,如下所示
List<string> allAircrafts = Directory.EnumerateFiles(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
@"\ApplicationName\Aircraft\"),
"*.lxml",
SearchOption.TopDirectoryOnly)
.Select(Path.GetFileNameWithoutExtension)
.ToList();
comboAircraft.ItemsSource = allAircrafts;
foreach (string item in allAircrafts)
{
var itemContainer = comboAircraft.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
itemContainer.Name = "comboAircraftItems" + itemContainer.Content;
}