Optimize LINQ Query for use with jQuery Autocomplete - vb.net

I'm working on building an HTTPHandler that will serve up plain text for use with jQuery Autocomplete. I have it working now except for when I insert the first bit of text it does not take me to the right portion of the alphabet.
Example: If I enter Ne
my drop down returns
Nlabama
Arkansas
Notice the "N" from Ne and the "labama" from "Alabama"
As I type the third character New, then the jQuery returns the "N" section of the results.
My current code looks like this
Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
''# the page ContentType is plain text
HttpContext.Current.Response.ContentType = "text/plain"
''# store the querystring as a variable'
Dim qs As Nullable(Of Integer) = Integer.TryParse(HttpContext.Current.Request.QueryString("ID"), Nothing)
''# use the RegionsDataContext'
Using RegionDC As New DAL.RegionsDataContext
''# create a (q)uery variable'
Dim q As Object
''# if the querystring PID is not blank'
''# then we want to return results based on the PID'
If Not qs Is Nothing Then
''# that fit within the Parent ID'
q = (From r In RegionDC.bt_Regions _
Where r.PID = qs _
Select r.Region).ToArray
''# now we loop through the array'
''# and write out the ressults'
For Each item In q
HttpContext.Current.Response.Write(item & vbCrLf)
Next
End If
End Using
End Sub
So where I'm at now is the fact that I stumbled on the "Part" portion of the Autocomplete method whereby I should only return information that is contained within the Part.
My question is, how would I implement this concept into my HTTPHandler without doing a fresh SQLQuery on every character change? IE: I do the SQL Query on the QueryString("ID"), and then on every subsequent load of the same ID, we just filter down the "Part".
http://www.example.com/ReturnRegions.axd?ID=[someID]&Part=[string]

Just grab the part from the querystring and use it in the Where clause to filter only Regions that start with it AND have the appropriate ID.
ToArray is not necessary

I changed my jQuery library to use the jQuery-UI and then built my iHttpHandler using a Singleton object in order to avoid hitting the database on every page load. The answer here seems to be working well for me.

Related

Streamwriter: write two listboxes on the same row

I am trying to write, in order to export on txt file, information in two listbox with the same number of rows. I have to export them with the following format: Listbox1, Listbox2. In order to do this, I've tried to use the following code:
Using writer = New StreamWriter(SaveFileDialog1.FileName)
For Each o As Object In Form3.ListBox1.Items And Form3.ListBox2.Items
writer.WriteLine(o)
Next
End Using
I'm receiving the following error:
BC30452 Operator 'And' is not defined for types 'ListBox.ObjectCollection' and 'ListBox.ObjectCollection'.
I've also tried to perform three For Each loops, the first for the LB1, the second for the commas and the third for LB2, but I'm having it exported with content on single lines. How could I solve this?
If you use Enumerable.Zip, as suggested in another answer, then you can make the code more succinct by doing away with the explicit loop:
File.WriteAllLines(SaveFileDialog1.FileName,
Form3.ListBox1.
Items.
Cast(Of Object).
Zip(Form3.ListBox2.
Items.
Cast(Of Object),
Function(x1, x2) $"{x1}, {x2}"))
If you didn't use Zip then you can use a loop this way:
Dim items1 = Form3.ListBox1.Items
Dim items2 = Form3.ListBox2.Items
Using writer = New StreamWriter(SaveFileDialog1.FileName)
For i = 0 To Math.Min(items1.Count, items2.Count)
writer.WriteLine($"{items1(i)}, {items2(i)}")
Next
End Using
The Math.Min part is just in case there are different numbers of items in each ListBox. If you know there aren't then you can do away with that and just use one Count. If there might be different counts but you want to output all items then the code would become slightly more complex to handle that.
As the error message says, the syntax you attempted is simply not valid. There's no feature in VB.NET that does that sort of thing.
However, the .NET Framework API does provide a means for something similar, which would probably work in your case. See Enumerable.Zip(). You can use it like this:
Using writer = New StreamWriter(SaveFileDialog1.FileName)
For Each o As String In Form3.ListBox1.Items.Cast(Of Object).Zip(Form3.ListBox2.Items.Cast(Of Object), Function(x1, x2) x1 & ", " & x2)
writer.WriteLine(o)
Next
End Using
Since you said that both list boxes have the same number of items we can use the number of items in the first listbox less one (indexes start at zero) in a For loop.
I used a StringBuilder so the code does not have to throw away and create a new string on each iteration.
I used an interpolated string indicate by the $ preceding the string. This means I can insert variables in braces, right along with literals.
Call .ToString on the StringBuilder to write to the text file.
Private Sub SaveListBoxes()
Dim sb As New StringBuilder
For i = 0 To ListBox1.Items.Count - 1
sb.AppendLine($"{ListBox1.Items(i)}, {ListBox2.Items(i)}")
Next
File.WriteAllText("C:\Users\xxx\Desktop\ListBoxText.txt", sb.ToString)
End Sub

VB.Net Read multi column text file and load into ListBox

First, I am not a programmer, I mainly just do simple scripts however there are somethings that are just easier to do in VB, I am pretty much self taught so forgive me if this sounds basic or if I can't explain it to well.
I have run into an issue trying to load a multi-column text file into a list box. There are two separate issues.
First issue is to read the text file and only grab the first column to use in the listbox, I am currently using ReadAllLines to copy the text file to a string first.
Dim RDPItems() As String = IO.File.ReadAllLines(MyDocsDir & "\RDPservers.txt")
However I am having a difficult time finding the correct code to only grab the first Column of this string to put in the listbox, if I use the split option I get an error that "Value of type '1-dimensional array of String' cannot be converted to 'String'"
The code looked like
frmRDP.lstRDP.Items.Add() = Split(RDPItems, ";", CompareMethod.Text)
This is the first hurdle, the second issue is what I want to do is if an item is selected from the List box, the value of the second column gets pulled into a variable to use.
This part I'm not even sure where to begin.
Example data of the text file
Server1 ; 10.1.1.1:3389
Server2 ; 192.168.1.1:8080
Server3 ; 172.16.0.1:9833
.....
When it's working the application will read a text file with a list of servers and their IPs and put the servers in a listbox, when you select the server from the listbox it and click a connect button it will then launch
c:\windows\system32\mstsc.exe /v:serverip
Any help would be appreciated, as I can hard code a large list of this into the VB application it would be easier to just have a text file with a list of servers and IPs to load instead.
The best practise for this would probably be to store your "columns" in a Dictionary. Declare this at class level (that is, outside any Sub or Function):
Dim Servers As New Dictionary(Of String, String)
When you load your items you read the file line-by-line, adding the items to the Dictionary and the ListBox at the same time:
Using Reader As New IO.StreamReader(IO.Path.Combine(MyDocsDir, "RDPservers.txt")) 'Open the file.
While Reader.EndOfStream = False 'Loop until the StreamReader has read the whole file.
Dim Line As String = Reader.ReadLine() 'Read a line.
Dim LineParts() As String = Line.Split(New String() {" ; "}, StringSplitOptions.None) 'Split the line into two parts.
Servers.Add(LineParts(0), LineParts(1)) 'Add them to the Dictionary. LineParts(0) is the name, LineParts(1) is the IP-address.
lstRDP.Items.Add(LineParts(0)) 'Add the name to the ListBox.
End While
End Using 'Dispose the StreamReader.
(Note that I used IO.Path.Combine() instead of simply concatenating the strings. I recommend using that instead for joining paths together)
Now, whenever you want to get the IP-address from the selected item you can just do for example:
Dim IP As String = Servers(lstRDP.SelectedItem.ToString())
Hope this helps!
EDIT:
Missed that you wanted to start a process with it... But it's like charliefox2 wrote:
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & Servers(lstRDP.SelectedItem.ToString()))
Edit: #Visual Vincent's answer is way cleaner. I'll leave mine, but I recommend using his solution instead. That said, scroll down a little for how to open the server. He's got that too! Upvote his answer, and mark it as correct!
It looks like you're trying to split an array. Also, ListBox.Items.Add() works a bit differently than the way you've written your code. Let's take a look.
ListBox.Items.Add() requires that you provide it with a string inside the parameters. So you would do it like this:
frmRDP.lstRDP.Items.Add(Split(RDPItems, ";", CompareMethod.Text))
But don't do that!
When you call Split(), you must supply it with a string, not an array. In this case, RDPItems is an array, so we can't split the entire thing at once. This is the source of the error you were getting. Instead, we'll have to do it one item at a time. For this, we can use a For Each loop. See here for more info if you're not familiar with the concept.
A For Each loop will execute a block of code for each item in a collection. Using this, we get:
For Each item In RDPItems
Dim splitline() As String = Split(item, ";") 'splits the item by semicolon, and puts each portion into the array
frmRDP.lstRDP.Items.Add(splitline(0)) 'adds the first item in the array
Next
OK, so that gets us our server list put in our ListBox. But now, we want to open the server that our user has selected. To do that, we'll need an event handler (to know when the user has double clicked something), we'll have to find out which server they selected, and then we'll have to open that server.
We'll start by handling the double click by creating a sub to deal with it:
Private Sub lstRDP_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles lstRDP.MouseDoubleClick
Next, we'll get what the user has selected. Here, we're setting selection equal to the index that the user has selected (in this case, the first item is 0, the second is 1, and so on).
Dim selection As Integer = lstRDP.SelectedIndex
Lastly, we need to open the server. I'm assuming you want to do that in windows explorer, but if I'm mistaken please let me know.
Dim splitline() As String = Split(RDPItems(selection), ";")
Dim location As String = Trim(splitline(1))
We'll need to split the string again, but you'll notice this time I'm choosing the item whose location in the array is the same as the index of the list box the user has selected. Since we added our items to our listbox in the order they were added to our array, the first item in our listbox will be the first in the array, and so on. The location of the server will be the second part of the split function, or splitline(1). I've also included the Trim() function, which will remove any leading or trailing spaces.
Finally, we need to connect to our server. We'll use Process.Start() to launch the process.
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & location)
For future reference, to first argument for Process.Start() is the location of the process, and the second argument is any argument the process might take (in this case, what to connect to).
Our final double click event handler looks something like this:
Private Sub lstRDP_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles lstRDP.MouseDoubleClick
Dim selection As Integer = lstRDP.SelectedIndex
Dim splitline() As String = Split(RDPItems(selection), ";")
Dim location As String = Trim(splitline(1))
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & location)
End Sub
A final note: You may need to put
Dim RDPItems() As String = IO.File.ReadAllLines(MyDocsDir & "\RDPservers.txt")
outside of a sub, and instead just inside your class. This will ensure that both the click handler and your other sub where you populate the list box can both read from it.

Need Suggestions For AutoSuggest For VB.NET ComboBox

To provide some context, I have a combobox that the user interacts with to select an insurance company. Unfortunately they don't require just the name; sometimes insurance companies have the same name, and the only way to distinguish between them is to use their address (eg a Medicare office in North Carolina vs. a Medicare office in South Carolina). What I've currently done is use the combobox's DrawItem event to draw a tooltip next to the ComboBox when the dropdown list is displayed. The list itself displays the insurance company names, but the tooltip will display the address of the currently selected company. The combobox is set to DropDownList, so it's impossible for them to pick anything but what's in the list.
Well, now I'm being told to change this. The users are no longer content to have to click the combobox or hit the arrow keys. They want comboboxes that they can type in and have an autosuggest list appear as they type. That's all well and good but this is where I'm running into a wall. My cute little scheme of using a tooltip can't work in that situation because the autosuggest list is a completely separate control. DrawItem doesn't touch it, and I can't find a way to custom draw the autosuggest list. The other problem is that autosuggest doesn't do duplicate entries, so even though I have two different insurance companies only one will appear in the list simply because they share the same name.
The only other idea I've had so far is to somehow scroll the dropdown list to the appropriate item upon the user pressing a key. But I can't figure out how to set the highlighted item in the dropdown list without setting selectedindex. If I use selectedindex, it goes ahead and replaces the text.
Does anyone have any suggestions for how to proceed? Am I on the right track, or do am I trying too hard and need to do something else entirely?
You could use a text field where the user types in their text, and narrow the selection in the dropbox down based on that. To get around the same-name-but-different-company problem, you could list the address of the company after the name in a parenthesis. If the user types in a name that is invalid, put up an error/warning icon next to the text field.
To update the selection at runtime, you can add an event listener to the text field and query the current text to decide whether it is a valid prefix, or not.
We do something similar at the company I'm at. To accomplish it, we utilize a web service through AJAX.
Essentially, you modify a standard textbox with an AJAX AutoCompleteExtender (ACE). This ace references a webservice (which I'll illustrate) that goes and gets the info the customer types in on the fly. It's pretty cool once it's up and running.
Here's an example:
.ascx
<asp:TextBox ID="txtInsuranceCompany" runat="server" TabIndex="520"
AutoComplete="Off"AutoCompleteType="Disabled" CssClass="asbSearch" Width="350px"></asp:TextBox>
<ajax:AutoCompleteExtender ID="aceInsuranceCompany" runat="server" CompletionSetCount="20"
MinimumPrefixLength="0" OnClientShown="resetPosition" ServiceMethod="LookupData"
ServicePath="~/WebLookUpService.asmx" TargetControlID="txtInsuranceCompany" UseContextKey="true">
</ajax:AutoCompleteExtender>
Something subtle is that you have to be sure you set the context key for your autocomplete extender, as well as create some functionality within your webservice to load your values (again, I'll illustrate).
.vb code-behind
Dim yourhardcodedlist As New List(Of String)
yourhardcodedlist.Add("Progressive")
yourhardcodedlist.Add("State Farm")
yourhardcodedlist.Add("USAA")
WebLookUpService.AddLookupValues(txtInsuranceCompany.ID, yourhardcodedlist.ToArray)
aceInsuranceCompany.ContextKey = public_var0 & ":" & public_var1 & ":" & txtInsuranceCompany.ID
Note that the "public_var0" "and public_var1" aren't mandatory. This is just illustrating how you could pass more information to your web service without actually passing it as a parameter (i.e. a colon-delimitted list, that you're web service function can parse out for use in a SQL statement or something).
Now for the webservice...(.asmx)
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<System.Web.Script.Services.ScriptService()> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class WebLookUpService
Inherits System.Web.Services.WebService
<System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()> _
Public Function LookupData(ByVal prefixText As String, ByVal count As Integer, ByVal contextKey As String) As String()
'Construct SQL statement to pull from database
'parsing the context key as necessary to construct your SQL statement (if necessary)
'Dim somethingForSql As String = contextKey.Split(":")
Dim suggestions As List(Of String) = New List(Of String)
Try
Using cnADO As SqlConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("PublicSafetyServer").ToString)
cnADO.Open()
Dim dt As DataTable = New DataTable
Dim da As New SqlDataAdapter
da.SelectCommand = New SqlCommand("<YourSQLStatement>")
da.Fill(dt)
Dim endRow As Integer = dt.Rows.Count
If endRow > count Then
endRow = count
End If
For i As Integer = 0 To endRow - 1
Dim des As String = dt.Rows(i).Item(field)
Dim val As String = dt.Rows(i).Item(field)
suggestions.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(des, val))
Next
End Using
Catch ex As Exception
'Throw Error
End Try
suggestions.Sort()
If suggestions.Count = 0 Then
suggestions.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(noneFound, ""))
End If
Return suggestions.ToArray()
End Function
What's cool is that you can add values deliberately through 'yourhardcodedlist' that will combine with any values you pull via the web-service. This way, you can add values directly if you can't add values to the database.

How can I read individual lines of a CSV file into a string array, to then be selectively displayed via combobox input?

I need your help, guys! :|
I've got myself a CSV file with the following contents:
1,The Compact,1.8GHz,1024MB,160GB,440
2,The Medium,2.4GHz,1024MB,180GB,500
3,The Workhorse,2.4GHz,2048MB,220GB,650
It's a list of computer systems, basically, that the user can purchase.
I need to read this file, line-by-line, into an array. Let's call this array csvline().
The first line of the text file would stored in csvline(0). Line two would be stored in csvline(1). And so on. (I've started with zero because that's where VB starts its arrays). A drop-down list would then enable the user to select 1, 2 or 3 (or however many lines/systems are stored in the file). Upon selecting a number - say, 1 - csvline(0) would be displayed inside a textbox (textbox1, let's say). If 2 was selected, csvline(1) would be displayed, and so on.
It's not the formatting I need help with, though; that's the easy part. I just need someone to help teach me how to read a CSV file line-by-line, putting each line into a string array - csvlines(count) - then increment count by one so that the next line is read into another slot.
So far, I've been able to paste the numbers of each system into an combobox:
Using csvfileparser As New Microsoft.VisualBasic.FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvfileparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvfileparser.Delimiters = New String() {","}
While Not csvfileparser.EndOfData
csvalue = csvfileparser.ReadFields()
combobox1.Items.Add(String.Format("{1}{0}", _
Environment.NewLine, _
csvalue(0)))
End While
End Using
But this only selects individual values. I need to figure out how selecting one of these numbers in the combobox can trigger textbox1 to be appended with just that line (I can handle the formatting, using the string.format stuff). If I try to do this using csvalue = csvtranslator.ReadLine , I get the following error message:
"Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
If I then put it as an array, ie: csvalue() = csvtranslator.ReadLine , I then get a different error message:
"Error 1 Number of indices is less than the number of dimensions of the indexed array."
What's the knack, guys? I've spent hours trying to figure this out.
Please go easy on me - and keep any responses ultra-simple for my newbie brain - I'm very new to all this programming malarkey and just starting out! :)
Structure systemstructure
Dim number As Byte
Dim name As String
Dim procspeed As String
Dim ram As String
Dim harddrive As String
Dim price As Integer
End Structure
Private Sub csvmanagement()
Dim systemspecs As New systemstructure
Using csvparser As New FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvparser.Delimiters = New String() {","}
csvalue = csvparser.ReadFields()
systemspecs.number = csvalue(0)
systemspecs.name = csvalue(1)
systemspecs.procspeed = csvalue(2)
systemspecs.ram = csvalue(3)
systemspecs.harddrive = csvalue(4)
systemspecs.optical = csvalue(5)
systemspecs.graphics = csvalue(6)
systemspecs.audio = csvalue(7)
systemspecs.monitor = csvalue(8)
systemspecs.software = csvalue(9)
systemspecs.price = csvalue(10)
While Not csvparser.EndOfData
csvalue = csvparser.ReadFields()
systemlist.Items.Add(systemspecs)
End While
End Using
End Sub
Edit:
Thanks for your help guys, I've managed to solve the problem now.
It was merely a matter calling loops at the right point in time.
I would recommend using FileHelpers to do the reading.
The binding shouldn't be an issue after that.
Here is the Quickstart for Delimited Records:
Dim engine As New FileHelperEngine(GetType( Customer))
// To Read Use:
Dim res As Customer() = DirectCast(engine.ReadFile("FileIn.txt"), Customer())
// To Write Use:
engine.WriteFile("FileOut.txt", res)
When you get the file read, put it into a normal class and just bind to the class or use the list of items you have to do custom stuff with the combobox. Basically, get it out of the file and into a real class asap, then things will be easier.
At least take a look at the library. After using it, we use a lot more simple flat files since it is so easy, and we haven't written a file access routine since (for that kinda stuff).
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx
I think your main problem is understanding how arrays work (hence the error message).
You can use split and join functions to convert strings into and out of arrays
dim s() as string = split("1,2,3",",") gives and array of strings with 3 elements
dim ss as string = join(s,",") gives you the string back
Firstly, it's actually really good that you are using the TextFieldParser for reading CSV files - most don't but you won't have to worry about extra commas and quoted text etc...
The Readline method only gives you the raw string, hence the "Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
What you may find easier with combo boxes etc is to use an object (e.g. 'systemspecs') rather than strings. Assign the CSV data to the objects and override the "ToString" method of the 'systemspecs' class to display in the combo box how you want with formatting etc. That way when you handle the SelectedIndexChanged event (or similar) you get the "SelectedItem" from the combo box (which can be Nothing so check) and cast it as the 'systemspecs' to use it. The advantage is that you are not restricted to display the exact data in the combo etc.
' in "systemspecs"...
Public Overrides Function ToString() As String
Return Name ' or whatever...
End Function ' ToString
e.g.
dim item as new systemspecs
item.ID = csvalue(1)
item.Name = csvalue(2)
' etc...
combobox1.Items.Add(item)
Let me know if that makes sense!
PK :-)

ComboBox DataBinding DisplayMember and LINQ queries

Update
I decided to iterate through the Data.DataTable and trimmed the values there.
Utilizing SirDemon's post, I have updated the code a little bit:
Sub test(ByVal path As String)
Dim oData As GSDataObject = GetDataObj(path)
EmptyComboBoxes()
Dim oDT As New Data.DataTable
Try
Dim t = From r In oData.GetTable(String.Format("SELECT * FROM {0}gsobj\paths ORDER BY keyid", AddBS(path))) Select r
If t.Count > 0 Then
oDT = t.CopyToDataTable
For Each dr As Data.DataRow In oDT.Rows
dr.Item("key_code") = dr.Item("key_code").ToString.Trim
dr.Item("descript") = dr.Item("descript").ToString.Trim
Next
dataPathComboBox.DataSource = oDT
dataPathComboBox.DisplayMember = "descript"
dataPathComboBox.ValueMember = "key_code"
dataPathComboBox.SelectedIndex = 0
dataPathComboBox.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
This works almost as I need it to, the data is originally from a foxpro table, so the strings it returns are <value> plus (<Field>.maxlength-<value>.length) of trailing whitespace characters. For example, a field with a 12 character length has a value of bob. When I query the database, I get "bob_________", where _ is a space.
I have tried a couple of different things to get rid of the whitespace such as:
dataPathComboBox.DisplayMember.Trim()
dataPathComboBox.DisplayMember = "descript".Trim.
But nothing has worked yet. Other than iterating through the Data.DataTable or creating a custom CopyToDataTable method, is there any way I can trim the values? Perhaps it can be done in-line with the LINQ query?
Here is the code I have so far, I have no problem querying the database and getting the information, but I cannot figure out how to display the proper text in the ComboBox list. I always get System.Data.DataRow :
Try
Dim t = From r In oData.GetTable("SELECT * FROM ../gsobj/paths ORDER BY keyid") _
Select r
dataPathComboBox.DataSource = t.ToList
dataPathComboBox.SelectedIndex = 0
'dataPathComboBox.DisplayMember = t.ToList.First.Item("descript")
dataPathComboBox.Enabled = True
Catch ex As Exception
Stop
End Try
I know that on the DisplayMember line the .First.Item() part is wrong, I just wanted to show what row I am trying to designate as the DisplayMember.
I'm pretty sure your code tries to set an entire DataRow to a property that is simply the name of the Field (in a strongly type class) or a Column (in a DataTable).
dataPathComboBox.DisplayMember = "descript"
Should work if the DataTable contains a retrieved column of that name.
Also, I'd suggest setting your SelectedIndex only AFTER you've done the DataBinding and you know you actually have items, otherwise SelectedIndex = 0 may throw an exception.
EDIT: Trimming the name of the bound column will trim just that, not the actual bound value string. You either have to go through all the items after they've been bound and do something like:
dataPathComboBox.Item[i].Text = dataPathComboBox.Item[i].Text.Trim()
For each one of the items. Not sure what ComboBox control you're using, so the item collection name might be something else.
Another solution is doing that for each item when it is bound if the ComboBox control exposes an onItemDataBound event of some kind.
There are plenty of other ways to do this, depending on what the control itself offers and what you choose to do.
DisplayMember is intended to indicate the name of the property holding the value to be displayed.
In your case, I'm not sure what the syntax will by since you seem to be using a DataSet, but that should be
... DisplayMember="Item['descript']" ...
in Xaml, unless you need to switch that at runtime in which case you can do it in code with
dataPathComboBox.DisplayMember = "Item['descript']"
Again, not 100% sure on the syntax. If you are using a strongly typed DataSet it's even easier since you should have a "descript" property on your row, but given hat your error indicates "System.DataRow" and not a custom type, I guess you are not.
Because I can't figure out the underlying type of the datasource you are using I suggest you to change commented string to
dataPathComboBox.DisplayMember = t.ElementType.GetProperties.GetValue(0).Name
and try to determine correct index (initially it is zero) in practice.