EF5 + ListView和实体

时间:2013-02-10 19:09:57

标签: c# wpf entity-framework xaml ef-code-first

我的项目中有以下课程,

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; }
}

用户希望使用以下方法保存日期访问过的区域

enter image description here

我希望只从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

的XAML
<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>

我认为我的问题应该有一个解决方案。

1 个答案:

答案 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;
}