我的项目中有以下课程,
public class Area
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ObservableCollection<VisitDetail> VisitDetails { get; set; }
}
public class VisitDetail
{
[Key]
public int VisitId { get; set; }
[Required]
public int AreaId { get; set; }
public Area Area { get; set; }
}
用户希望使用以下方法保存日期访问过的区域。
我希望只从ListView
获取选定的区域来保存它们。当我试图让那些使用ListView.Items[index].IsSelected
时,它会抛出一个错误,
Unable to cast object of type 'Namespace.Area' to type 'System.Windows.Controls.ListViewItem'
请告诉我解决问题的确切方法。
修改1:
我的项目是在WPF中。请注意,当加载访问详细信息窗口时,Area
实体集合与ListView.ItemsSource
绑定。
(由于WPF,没有任何ListView.CheckedItems
:(
)
编辑2:
感谢@blins您的解决方案有效。但我无法获得检查项目。我在这里发布我的xaml。但是,我可以获得选定的项目。如果我能拿到那些经过检查的物品,我会很高兴。
这是我ListView
<ListView Name="lvList" SelectionMode="Multiple" ClipToBounds="True" >
<ListView.View>
<GridView >
<GridViewColumn DisplayMemberBinding="{Binding Id}" />
<GridViewColumn Header="Area" >
<GridViewColumn.CellTemplate>
<DataTemplate >
<CheckBox x:Name="checkbox" Content="{Binding Name}" IsChecked="{Binding Path=IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
我认为我的问题应该有一个解决方案。
答案 0 :(得分:0)
抛出异常是因为ListView的Items属性实际上表示用于生成列表内容的项目列表(即,它们不是ListViewItem类型,而是您的Area类型)。这就是WPF运行的方式,在这种情况下你需要的是向底层ItemsControl的ItemContainerGenerator询问与UI中项目对应的ListViewItem。
XAML:
<ListView Name="listView1" />
代码(假设您已经设置了ListView的DataContext和ItemsSource等):
ListViewItem item = listView1
.ItemContainerGenerator
.ContainerFromIndex(0) as ListViewItem;
item.IsSelected = true;
如果您不了解/关心列表中的索引,而是您知道该项目,那么另一种选择。
ListViewItem item = listView1
.ItemContainerGenerator
.ContainerFromItem(someAreaInstance) as ListViewItem;
回答问题第2部分:
你真的应该更深入地研究MVVM模式,这将有助于你避免这种情况开始,但这是一种方法来做你想要的。首先,你可能想要一个类似下面的辅助方法(未经测试):
static FrameworkElement GetVisualDescendantByName(DependencyObject control, string name)
{
// Recurse
FrameworkElement el = null;
int nChildren = VisualTreeHelper.GetChildrenCount(control);
for (int i = 0; i < nChildren; i++)
{
var child = VisualTreeHelper.GetChild(control, i);
el = GetVisualDescendantByName(child, name);
if (el != null)
return el;
}
// See if control is a match
if (control is FrameworkElement)
{
el = control as FrameworkElement;
if (el.Name == name)
return control as FrameworkElemdent;
}
return null;
}
你可以做点像......
foreach (var item in lvList.Items)
{
var listItem = lvList.ItemContainerGenerator
.ContainerFromItem(item) as ListViewItem;
CheckBox cb = GetVisualDescendantByName(listItem, "checkbox") as CheckBox;
// Do stuff with CheckBox...
var myVar = cb.IsChecked;
}