Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Two Different Filters for Two Different Listboxes

Posted on 2016-09-23
3
Medium Priority
?
68 Views
Last Modified: 2016-09-23
I want one listbox on a vb.net form to display records in a datatable that have "Selected = 0" (note: "Selected is a field in the datatable) and another listbox on the form to display records in the datatable that have "Selected = 1".  I wrote the posted code, but when I set the filter for bs2 it appears to affect both listboxes, even though the first listbox's datasource is bs1.  Why does this happen, and how can I set a different filter for each listbox?

    Private Sub SelectItems_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim cn As New SqlConnection(strConn)
        Dim SQL As String

        SQL = "SELECT UserId As Id, FullName As Name, 0 As Selected FROM Users WHERE Terminated = 0"
        Using da As New SqlDataAdapter(SQL, cn)
            da.Fill(dt)
        End Using
        bs1.DataSource = dt
        bs1.Sort = "Name"
        bs1.Filter = "Selected = 0"
        lbxUnSelectedItems.DataSource = bs1
        lbxUnSelectedItems.ValueMember = "Id"
        lbxUnSelectedItems.DisplayMember = "Name"

        bs2.DataSource = dt
        bs2.Sort = "Name"
        bs2.Filter = "Selected = 1"
        lbxSelectedItems.DataSource = bs2
        lbxSelectedItems.ValueMember = "Id"
        lbxSelectedItems.DisplayMember = "Name"

        cn = Nothing

    End Sub

Open in new window

0
Comment
Question by:Declan_Basile
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 27

Accepted Solution

by:
Shaun Kline earned 2000 total points
ID: 41812670
When you set the DataSource property, you are only setting a pointer to the underlying data object. So when you change the properties of each binding source, you are affecting the same underlying data object. (Details can be seen here https://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.filter(v=vs.110).aspx in the Remarks section.)

When setting the DataSource property, try this:
bs1.DataSource = New DataView(dt)
bs2.DataSource = New DataView(dt)

Open in new window


This should create two distinct data objects.
0
 
LVL 34

Expert Comment

by:it_saige
ID: 41812731
*NO POINTS*

Exactly what Shaun stated.  Here is a simple proof of concept:

Form1.vb -
Imports System.Runtime.CompilerServices
Imports System.ComponentModel

Public Class Form1
	Private table1 As DataTable = Nothing
	Private table2 As DataTable = Nothing

	Private Sub OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
		If table1 IsNot Nothing Then table1.Dispose()
		If table2 IsNot Nothing Then table2.Dispose()
		table1 = (From i In Enumerable.Range(0, 20) Select New With {.ID = i, .Name = String.Format("Name{0}", i), .Selected = i Mod 2 = 0}).ConvertToDataTable()
		table2 = (From i In Enumerable.Range(0, 20) Select New With {.ID = i, .Name = String.Format("Name{0}", i), .Selected = i Mod 2 = 0}).ConvertToDataTable()

		BindingSource1.DataSource = table1
		BindingSource2.DataSource = table1
		ListBox1.DataSource = BindingSource1
		ListBox1.ValueMember = "ID"
		ListBox1.DisplayMember = "Name"
		ListBox2.DataSource = BindingSource2
		ListBox2.ValueMember = "ID"
		ListBox2.DisplayMember = "Name"
	End Sub

	Private Sub OnClick(sender As Object, e As EventArgs) Handles Button1.Click
		If BindingSource2.DataSource Is table1 Then
			BindingSource2.DataSource = table2
		Else
			BindingSource2.DataSource = table1
		End If

		If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then BindingSource1.Filter = TextBox1.Text
		If Not String.IsNullOrWhiteSpace(TextBox2.Text) Then BindingSource2.Filter = TextBox2.Text
	End Sub

	Private Sub OnValidated(sender As Object, e As EventArgs) Handles TextBox2.Validated, TextBox1.Validated
		If Typeof sender Is TextBox Then
			Dim tb = DirectCast(sender, TextBox)
			If Not String.IsNullOrWhiteSpace(tb.Text) Then
				If tb.Equals(TextBox1) Then
					BindingSource1.Filter = tb.Text
				ElseIf tb.Equals(TextBox2) Then
					BindingSource2.Filter = tb.Text
				End If
			End If
		End If
	End Sub
End Class

Module Extensions
	<Extension()> _
	Public Function ConvertToDataTable(Of T)(ByVal source As IEnumerable(Of T)) As DataTable
		Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
		Dim table As DataTable = New DataTable()

		For i As Integer = 0 To properties.Count - 1
			Dim [property] As PropertyDescriptor = properties(i)
			If [property].PropertyType.IsGenericType AndAlso [property].PropertyType.GetGenericTypeDefinition().Equals(GetType(Nullable)) Then
				table.Columns.Add([property].Name, [property].PropertyType.GetGenericArguments()(0))
			Else
				table.Columns.Add([property].Name, [property].PropertyType)
			End If
		Next

		Dim values(properties.Count - 1) As Object
		For Each item As T In source
			For i As Integer = 0 To properties.Count - 1
				values(i) = properties(i).GetValue(item)
			Next
			table.Rows.Add(values)
		Next

		Return table
	End Function
End Module

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.components = New System.ComponentModel.Container()
		Me.ListBox1 = New System.Windows.Forms.ListBox()
		Me.ListBox2 = New System.Windows.Forms.ListBox()
		Me.Label1 = New System.Windows.Forms.Label()
		Me.Label2 = New System.Windows.Forms.Label()
		Me.TextBox1 = New System.Windows.Forms.TextBox()
		Me.TextBox2 = New System.Windows.Forms.TextBox()
		Me.Button1 = New System.Windows.Forms.Button()
		Me.BindingSource1 = New System.Windows.Forms.BindingSource(Me.components)
		Me.BindingSource2 = New System.Windows.Forms.BindingSource(Me.components)
		CType(Me.BindingSource1, System.ComponentModel.ISupportInitialize).BeginInit()
		CType(Me.BindingSource2, System.ComponentModel.ISupportInitialize).BeginInit()
		Me.SuspendLayout()
		'
		'ListBox1
		'
		Me.ListBox1.FormattingEnabled = True
		Me.ListBox1.Location = New System.Drawing.Point(13, 13)
		Me.ListBox1.Name = "ListBox1"
		Me.ListBox1.Size = New System.Drawing.Size(200, 238)
		Me.ListBox1.TabIndex = 0
		'
		'ListBox2
		'
		Me.ListBox2.FormattingEnabled = True
		Me.ListBox2.Location = New System.Drawing.Point(219, 13)
		Me.ListBox2.Name = "ListBox2"
		Me.ListBox2.Size = New System.Drawing.Size(200, 238)
		Me.ListBox2.TabIndex = 1
		'
		'Label1
		'
		Me.Label1.AutoSize = True
		Me.Label1.Location = New System.Drawing.Point(12, 261)
		Me.Label1.Name = "Label1"
		Me.Label1.Size = New System.Drawing.Size(32, 13)
		Me.Label1.TabIndex = 2
		Me.Label1.Text = "Filter:"
		'
		'Label2
		'
		Me.Label2.AutoSize = True
		Me.Label2.Location = New System.Drawing.Point(219, 260)
		Me.Label2.Name = "Label2"
		Me.Label2.Size = New System.Drawing.Size(32, 13)
		Me.Label2.TabIndex = 3
		Me.Label2.Text = "Filter:"
		'
		'TextBox1
		'
		Me.TextBox1.Location = New System.Drawing.Point(50, 258)
		Me.TextBox1.Name = "TextBox1"
		Me.TextBox1.Size = New System.Drawing.Size(163, 20)
		Me.TextBox1.TabIndex = 4
		'
		'TextBox2
		'
		Me.TextBox2.Location = New System.Drawing.Point(257, 257)
		Me.TextBox2.Name = "TextBox2"
		Me.TextBox2.Size = New System.Drawing.Size(162, 20)
		Me.TextBox2.TabIndex = 5
		'
		'Button1
		'
		Me.Button1.Location = New System.Drawing.Point(13, 292)
		Me.Button1.Name = "Button1"
		Me.Button1.Size = New System.Drawing.Size(406, 23)
		Me.Button1.TabIndex = 6
		Me.Button1.Text = "Change Data Sources"
		Me.Button1.UseVisualStyleBackColor = True
		'
		'Form1
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(436, 327)
		Me.Controls.Add(Me.Button1)
		Me.Controls.Add(Me.TextBox2)
		Me.Controls.Add(Me.TextBox1)
		Me.Controls.Add(Me.Label2)
		Me.Controls.Add(Me.Label1)
		Me.Controls.Add(Me.ListBox2)
		Me.Controls.Add(Me.ListBox1)
		Me.Name = "Form1"
		Me.Text = "Form1"
		CType(Me.BindingSource1, System.ComponentModel.ISupportInitialize).EndInit()
		CType(Me.BindingSource2, System.ComponentModel.ISupportInitialize).EndInit()
		Me.ResumeLayout(False)
		Me.PerformLayout()

	End Sub
	Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
	Friend WithEvents ListBox2 As System.Windows.Forms.ListBox
	Friend WithEvents Label1 As System.Windows.Forms.Label
	Friend WithEvents Label2 As System.Windows.Forms.Label
	Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
	Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
	Friend WithEvents Button1 As System.Windows.Forms.Button
	Friend WithEvents BindingSource1 As System.Windows.Forms.BindingSource
	Friend WithEvents BindingSource2 As System.Windows.Forms.BindingSource

End Class

Open in new window

Produces the following output -

Initial load:Capture.JPGSetting the filter for the first listbox:Capture.JPGNow setting the filter for the second listbox:Capture.JPGIf we click the 'Change Data Sources' button to use separate datasources:Capture.JPG
-saige-
0
 
LVL 1

Author Closing Comment

by:Declan_Basile
ID: 41813059
Excellent!  That's exactly what I needed to know.  Thank you.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question