Binding ListView Throws Window должен быть корнем дерева. Невозможно добавить Window как дочерний элемент Visual - PullRequest
0 голосов
/ 30 января 2011

Я пытаюсь привязать ObservableCollection к ListView, но когда я пытаюсь отладить программу, VS2010 выдает исключение "Окно должно быть корнем дерева. Невозможно добавить Окно как дочерний элемент 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 ]

1 голос
/ 04 февраля 2011

Попробуйте поменять коллекцию emergencyContactsCollection на публичное свойство (т. Е. EmergencyContacts) объекта test_ListView.Установите для DataContext lst_EmergencyContacts значение EmergencyContactsCollection.

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

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

Управление таким способом привязки данных часто значительно облегчает задачу.Еще лучше было бы отделить привязанные к данным свойства к их собственной модели представления.

0 голосов
/ 07 февраля 2011

В итоге я использовал 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>

Спасибо за ваше время и помощь.

Мэтт

...