-
Dec 14th, 2020, 09:54 AM
#1
Thread Starter
New Member
Selecting First element with IQueryable
Hi Guys,
I am working on a Windows Phone Contacts app and I am trying to make a query of the first IEnumerable element in the variable "contacts".
The output has to be shown in the Listbox under the variable "firstperson".
Currently the output returns all elements even when I added .First() after the firstperson variabele.
Hope you guys can help me out!
Here is my code:
Code:
Imports System
Imports System.Threading
Imports System.Windows.Controls
Imports Microsoft.Phone.Controls
Imports Microsoft.Phone.Shell
Imports System.IO
Imports System.Xml.Serialization
Imports System.Linq
Imports System.Xml.Linq
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
SupportedOrientations = SupportedPageOrientation.Portrait Or SupportedPageOrientation.Landscape
'Uitlezen en sorteren elementen op "Voornaam" Contacten.xml
Dim document = XDocument.Load("Assets\Contacten.xml")
Dim element As XElement = XElement.Load("Assets\Contacten.xml", LoadOptions.None)
Dim elementSorted As XElement() = element.Elements("Persoon").OrderBy(Function(t) CStr(t.Element("Voornaam"))).ToArray()
Dim contacts = elementSorted.[Select](Function(t) New Contact() With {
.Achternaam = t.Element("Achternaam").Value,
.Voornaam = t.Element("Voornaam").Value,
.Emailadres = t.Element("Emailadres").Value
})
Dim firstperson As IQueryable(Of Contact) = contacts.AsQueryable().Where(Function(person) person.Voornaam.Any())
firstperson.First()
ContactListBox.DataContext = firstperson
End Sub
Public Class Contact
<XmlElement("Achternaam")>
Public Property Achternaam As String
<XmlElement("Voornaam")>
Public Property Voornaam() As String
<XmlElement("Emailadres")>
Public Property Emailadres() As String
<XmlElement("Geboortedatum")>
Public Property Geboortedatum() As String
<XmlElement("Telefoon")>
Public Property Telefoon() As String
<XmlElement("Fotobestand")>
Public Property Fotobestand() As String
<XmlElement("Fotolink")>
Public Property Fotolink() As String
End Class
End Class
Last edited by dday9; Dec 14th, 2020 at 09:55 AM.
Reason: Added Code Tags
-
Dec 14th, 2020, 10:12 AM
#2
Re: Selecting First element with IQueryable
You get the first item in the list but you don't put it anywhere, so it is immediately discarded. You then proceed to use the whole list. You should start by using variable names that actually describe what they refer to. Your firstperson variable doesn't actually refer to the first person at all. If you were to get rid of the Where call and just use First, which does the filtering and selecting, then it would be a reasonable name:
vb.net Code:
Dim firstPerson = contacts.AsQueryable().First(Function(person) person.Voornaam.Any())
ContactListBox.DataContext = firstPerson
-
Dec 14th, 2020, 10:32 AM
#3
Thread Starter
New Member
Re: Selecting First element with IQueryable
Hi jmcilhinney,
Thanks for your fast reply!
The weird thing is, when I try your suggestion the listbox doesn't give any output, while it does with the "Where"-construction (this shows all items):
Attachment 179576
For what its worth I placed the XAML code of the Listbox (output) where the binding elements are:
Code:
<Run Text="{Binding Voornaam}"/>
<Run Text="{Binding Achternaam}"/>
<Grid x:Name="SavedContactsPanel" Margin="0,306,0,0">
<TextBlock Text="Opgeslagen contacten:" HorizontalAlignment="Left" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" FontSize="25" Width="405" Height="41" VerticalAlignment="Top" Margin="41,10,0,0" />
<ListBox x:Name="ContactListBox" ItemsSource="{Binding}" MaxHeight="{Binding ElementName=ContactListBox, Path=ActualHeight}" HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="28,51,0,10" Width="405" >
<ListBox.ItemTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<StackPanel Grid.Row="0" Orientation="Horizontal" >
<TextBlock Style="{StaticResource PhoneTextSubtleStyle}" FontSize="25" >
<Run Text="{Binding Voornaam}"/>
<Run Text="{Binding Achternaam}"/>
</TextBlock>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
If there are any other ways to obtain the first element from my xml file, they are welcome
Last edited by dday9; Dec 14th, 2020 at 11:13 AM.
-
Dec 14th, 2020, 11:16 AM
#4
Re: Selecting First element with IQueryable
Welcome to VBForums, Lenn86!
I wanted to give you a heads up that your first couple of posts will need to be approved by a moderator so they won't immediately show up. However, once you post once, there's no need to post again.
Also, be sure to make use of code tags. You'll noticed that both of your posts have edits to them, that was me adding code tags. If you need help on using them, visit the link in my signature.
Edit - Also, I moved this thread to the WPF forum.
Last edited by dday9; Dec 14th, 2020 at 11:19 AM.
-
Dec 31st, 2020, 11:16 PM
#5
Member
Re: Selecting First element with IQueryable
Hello, @Lenn86
Please try this code, To Selecting First element with IQueryable
Code:
public static TSource First<TSource> (this System.Linq.IQueryable<TSource> source);
I hope this code will be useful to you.
Thank you.
< advertising removed by moderator >
-
Dec 31st, 2020, 11:22 PM
#6
Re: Selecting First element with IQueryable
 Originally Posted by Sherin
Hello, @Lenn86
Please try this code, To Selecting First element with IQueryable
Code:
public static TSource First<TSource> (this System.Linq.IQueryable<TSource> source);
I hope this code will be useful to you.
Thank you.
The OP can't "try that code". That's the declaration of the method they need to call. It doesn't indicate at all how they should call it. Fortunately, I demonstrated how to call that method over two weeks ago, so I'm just wondering exactly what value you thought this post would provide. Perhaps you aren't aware that a moderator has removed the advertising from your signature so posting useless information isn't a actually working to sneak in spam.
-
Jan 1st, 2021, 08:23 AM
#7
Thread Starter
New Member
Re: Selecting First element with IQueryable
Yeah the .Take(1) shows the first item after deserialization, but still weird why indexation ( e.g. .First) still does not work??
The program runs correctly (Option Explicit is on), the list is displayed in the control, but when I use indexation, the listbox control doesn't display anything.
I think the indexation somehow can't be applied after deserialization (maybe invalid corresponding XMLElements??)
The updated code below:
Class Persoon
Code:
<XmlRoot(ElementName:="Adresboek")>
Public Class Persoon
Private _achternaam As String
Private _voornaam As String
Private _emailadres As String
<XmlElement(ElementName:="Achternaam")>
Public Property Achternaam() As String
Get
Return _achternaam
End Get
Set(ByVal value As String)
_achternaam = value
End Set
End Property
<XmlElement(ElementName:="Voornaam")>
Public Property Voornaam() As String
Get
Return _voornaam
End Get
Set(ByVal value As String)
_voornaam = value
End Set
End Property
<XmlElement(ElementName:="Emailadres")>
Public Property Emailadres() As String
Get
Return _emailadres
End Get
Set(ByVal value As String)
_emailadres = value
End Set
End Property
End Class
The Mainpage class:
Code:
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
SupportedOrientations = SupportedPageOrientation.Portrait Or SupportedPageOrientation.Landscape
'Write default XML data to XML-file
Dim xmlWriterSettings As XmlWriterSettings = New XmlWriterSettings()
xmlWriterSettings.Indent = True
Using myIsolatedStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Using writeStream As IsolatedStorageFileStream = myIsolatedStorage.OpenFile("Contacten.xml", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Persoon)))
Using xmlWriter As XmlWriter = xmlWriter.Create(writeStream, xmlWriterSettings)
serializer.Serialize(xmlWriter, GeneratePersonData())
End Using
End Using
End Using
'Read and sort XML data by Voornaam to Object Persoon and show first item in list
Try
Using myIsolatedStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Using readStream As IsolatedStorageFileStream = myIsolatedStorage.OpenFile("Contacten.xml", FileMode.Open)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Persoon)))
Dim data As List(Of Persoon) = CType(serializer.Deserialize(readStream), List(Of Persoon))
Dim dataSorted = data.OrderBy(Function(x) x.Voornaam).ToList
Dim contactList As New List(Of Persoon)
contactList = dataSorted
Dim first = contactList(0)
ContactListBox.DataContext = first
End Using
End Using
Catch
End Try
'Dim path As String = "Assets\Contacten.xml"
'Dim serializer = New XmlSerializer(GetType(Adresboek))
'Dim streamReader = New FileStream(path, FileMode.Open)
'Dim readContainer = TryCast(serializer.Deserialize(streamReader), Adresboek)
'ContactListBox.DataContext = readContainer
'streamReader.Close()
End Sub
'Generate default list Persoon and add items to list
Private Function GeneratePersonData() As List(Of Persoon)
Dim data As List(Of Persoon) = New List(Of Persoon)()
data.Add(New Persoon() With {
.Achternaam = "van Gaal",
.Voornaam = "Louis",
.Emailadres = "louisvangaal@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "Kluivert",
.Voornaam = "Patrick",
.Emailadres = "patrickkluivert@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "van Persie",
.Voornaam = "Robin",
.Emailadres = "robinvanpersie@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "Robben",
.Voornaam = "Arjen",
.Emailadres = "arjenrobben@prive.nl"
})
Return data
End Function
End Class
-
Jan 1st, 2021, 08:32 AM
#8
Thread Starter
New Member
Re: Selecting First element with IQueryable
So when I use the code below all items are displayed correctly:
The Mainpage class:
Code:
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
SupportedOrientations = SupportedPageOrientation.Portrait Or SupportedPageOrientation.Landscape
'Write default XML data to XML-file
Dim xmlWriterSettings As XmlWriterSettings = New XmlWriterSettings()
xmlWriterSettings.Indent = True
Using myIsolatedStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Using writeStream As IsolatedStorageFileStream = myIsolatedStorage.OpenFile("Contacten.xml", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Persoon)))
Using xmlWriter As XmlWriter = xmlWriter.Create(writeStream, xmlWriterSettings)
serializer.Serialize(xmlWriter, GeneratePersonData())
End Using
End Using
End Using
'Read and sort XML data by Voornaam to Object Persoon and show first item in list
Try
Using myIsolatedStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Using readStream As IsolatedStorageFileStream = myIsolatedStorage.OpenFile("Contacten.xml", FileMode.Open)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Persoon)))
Dim data As List(Of Persoon) = CType(serializer.Deserialize(readStream), List(Of Persoon))
Dim dataSorted = data.OrderBy(Function(x) x.Voornaam).ToList
ContactListBox.DataContext = dataSorted
'ContactListBox.DataContext = dataSorted.Take(1) also works
End Using
End Using
Catch
End Try
End Sub
'Generate default list Persoon and add items to list
Private Function GeneratePersonData() As List(Of Persoon)
Dim data As List(Of Persoon) = New List(Of Persoon)()
data.Add(New Persoon() With {
.Achternaam = "van Gaal",
.Voornaam = "Louis",
.Emailadres = "louisvangaal@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "Kluivert",
.Voornaam = "Patrick",
.Emailadres = "patrickkluivert@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "van Persie",
.Voornaam = "Robin",
.Emailadres = "robinvanpersie@prive.nl"
})
data.Add(New Persoon() With {
.Achternaam = "Robben",
.Voornaam = "Arjen",
.Emailadres = "arjenrobben@prive.nl"
})
Return data
End Function
End Class
-
Jan 1st, 2021, 12:08 PM
#9
Thread Starter
New Member
-
Jan 1st, 2021, 11:04 PM
#10
Re: Selecting First element with IQueryable
For a start, the First method doesn't involve any indexing. First involves enumerating. Basically, a For Each loop is used to enumerate the list and the current item is returned in the first iteration.
As for the issue, the problem is presumably that the DataContext property requires that you assign a list to it, not a single item. If you only want to display a single item then create a list that contains it and assign that.
-
Jan 2nd, 2021, 07:00 AM
#11
Thread Starter
New Member
Re: Selecting First element with IQueryable
"I was blind, now I can see" This problem is solved, thanks for all your assistance jmcihinney!
Greetings and best wishes from the Netherlands.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|