绑定ListView引发窗口必须是树的根。无法将Window添加为Visual的子级

时间:2011-01-30 14:16:10

标签: wpf vb.net .net-3.5

我试图将ObservableCollection绑定到ListView但是当我尝试调试程序时VS2010抛出异常“Window必须是树的根。不能将Window添加为Visual的子”

如果我要删除尝试过的ItemsSource绑定,WPF窗口会打开(显然listView中没有任何数据)。我在我的代码隐藏中创建了一个Sub,它解析XML文件并将值添加到ObservableCollection中,然后绑定ListView。

我已逐步完成代码,并且错误似乎出现在XAML中,因为Sub完成且没有错误,每次CodeBehind完成后程序错误。

我的XAML文件如下:

<Window x:Class="test_ListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="test_ListView" Height="300" Width="300">
    <Grid>
        <ListView Height="105" HorizontalAlignment="Left" Name="lst_EmergencyContacts" VerticalAlignment="Top" Width="478">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" Width="160" />
                    <GridViewColumn DisplayMemberBinding="{Binding emContactsNumber}" Header="Number" Width="70" />
                    <GridViewColumn DisplayMemberBinding="{Binding emContactsPhoneCoverage}" Header="Phone Coverage" Width="95" />
                    <GridViewColumn DisplayMemberBinding="{Binding distListPhone}" Header="Distance" Width="60" />
                    <GridViewColumn Header="More" Width="60" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

虽然我认为错误在XAML中,但我会包含CodeBehind详细信息,以防万一(因为如果没有调用Sub绑定ListView,程序将运行时没有错误。)

    Public Property emContactsName() As String
        Get
            Return em_Name
        End Get
        Set(ByVal value As String)
            em_Name = value
        End Set
    End Property
    Private em_Name As String
    Public Property emContactsNumber() As String
        Get
            Return em_Number
        End Get
        Set(ByVal value As String)
            em_Number = value
        End Set
    End Property
    Private em_Number As String
    Public Property emContacts27Mhz() As String
        Get
            Return em_27Mhz
        End Get
        Set(ByVal value As String)
            em_27Mhz = value
        End Set
    End Property
    Private em_27Mhz As String
    Public Property emContactsUhf() As String
        Get
            Return em_Uhf
        End Get
        Set(ByVal value As String)
            em_Uhf = value
        End Set
    End Property
    Private em_Uhf As String
    Public Property emContactsVhf() As String
        Get
            Return em_Vhf
        End Get
        Set(ByVal value As String)
            em_Vhf = value
        End Set
    End Property
    Private em_Vhf As String
    Public Property IsSelected() As Boolean
        Get
            Return m_IsSelected
        End Get
        Set(ByVal value As Boolean)
            m_IsSelected = value
        End Set
    End Property
    Private m_IsSelected As Boolean
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        getEmergencyContactsData("\", "EmergencyContacts.xml")
    End Sub

Private Sub getEmergencyContactsData(ByVal docPath As String, ByVal docName As String)
        Try
            Dim xDoc As XmlDocument = New XmlDocument
            Dim nList As XmlNodeList
            Dim node As XmlNode
            xDoc.Load(docPath + docName)
            nList = xDoc.SelectNodes("/items/item")
            Dim emergencyContactsCollection As New ObservableCollection(Of test_googleLookup)()
            For Each node In nList
                Dim eID = node.Attributes.GetNamedItem("id").Value
                Dim eName = node.ChildNodes.Item(0).InnerText
                Dim eNumber = node.ChildNodes.Item(1).InnerText
                Dim eRadio27Mhz = node.ChildNodes.Item(2).InnerText
                Dim eRadioUhf = node.ChildNodes.Item(3).InnerText
                Dim eRadioVhf = node.ChildNodes.Item(4).InnerText
                emergencyContactsCollection.Add(New test_googleLookup() With {.emContactsName = eName, .emContactsNumber = eNumber, .emContacts27Mhz = eRadio27Mhz, .emContactsUhf = eRadioUhf, .emContactsVhf = eRadioVhf, .IsSelected = 0})
            Next
            ' Add to resources
            Resources("emergencyContactsCollection") = emergencyContactsCollection
            lst_EmergencyContacts.ItemsSource = emergencyContactsCollection
        Catch
        End Try
    End Sub

我可以看到,在逐步调试时,XML文件正在被正确解析,并且值被添加到ObservableCollection中。

如果有人能提供任何帮助,我们将不胜感激。

感谢。

2 个答案:

答案 0 :(得分:1)

尝试将emergencyContactsCollection更改为test_ListView的公共属性(即,EmergencyContacts)。将lst_EmergencyContacts的DataContext设置为EmergencyContactsCollection。

<Window x:Class="test_ListView" ... DataContext="{Binding RelativeSource={RelativeSource Self}}">

<ListView Name="lst_EmergencyContacts" ... DataContext="{Binding Path=EmergencyContacts}">

以这种方式管理数据绑定通常会使事情变得更加容易。更好的方法是将数据绑定的属性分离到它们自己的ViewModel。

答案 1 :(得分:0)

我最终使用ListBoxes,下面是我使用的代码,万一有人感兴趣:

<ListBox Grid.Row="1" Grid.Column="0" Grid.RowSpan="4" Grid.ColumnSpan="3" HorizontalAlignment="Stretch"  ItemsSource="{DynamicResource emergencyContactsCollection}" Name="lst_emergencyServices" VerticalAlignment="Stretch">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox IsChecked="{Binding emerContIsSelected, Mode=TwoWay}" />
                                    <TextBlock Text="{Binding emerContName}" />
                                    <TextBlock Text="{Binding emerContNumber}" />
                                    <TextBlock Text="{Binding emerContRadio27mhz}" />
                                    <TextBlock Text="{Binding emerContRadioUhf}" />
                                    <TextBlock Text="{Binding emerContRadioVhf}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

感谢您的时间和帮助。

马特