By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,009 Members | 1,487 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,009 IT Pros & Developers. It's quick & easy.

Data Binding Question

P: n/a
Think it is great the way that you can set up a datsource, value member, and
display member for a combobox, and map a 'code' to a 'description' and back
again by binding the combobox to a datasource that contains the code. Now
suppose that you want it to be read-only? That is, you have the 'code' in
your DB, want the associated 'description' to display, but not let the user
change it on this particular form. There is no read-only property for a
combobox like with a textbox, and there are no datasource, display member,
value member properties for a textbox or label controls. Is there some easy
way to accomplish this? The only way I can think to do this is to use the
binding class 'format' event to lookup the description myself. Any other
ideas?

--
Terry
Nov 5 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Terry,

I thought that it was easily just this one, however I am in doubt.

Dropdownlist

http://msdn2.microsoft.com/en-us/lib...le(VS.71).aspx

Cor

Nov 5 '07 #2

P: n/a
The user can still change the selected index. And while I could change the
'Data Source Update Mode' (under advanced binding) to Never, this would be
confusing. Really want to show it in a label or readonly text box so the
user is aware that he/she can not change it (here).
--
Terry
"Cor Ligthert[MVP]" wrote:
Terry,

I thought that it was easily just this one, however I am in doubt.

Dropdownlist

http://msdn2.microsoft.com/en-us/lib...le(VS.71).aspx

Cor

Nov 5 '07 #3

P: n/a
Terry,

Why are you then binding it, just fill the itemarray with the fields you
want and you are ready.

This needs really only the most simple for each loop there is.

Cor

Nov 6 '07 #4

P: n/a
Hi Terry,

If we could custom draw the input box part of a ComboBox as well as its
items in the drop down list, a possible workaround may be custom drawing
the ComboBox to get what you want.

Unfortunately, we can not custom draw the input box part of a ComboBox.

IMO, the solution to use the Binding class's Format event to look up the
description youself you have mentioned in your first reply is good. In
addition, I think it would be better to create a custom control to
encapsulate the above logic. Then you could use this custom control
wherever you want.

The following is a sample of this custom control. Note that you shoud set
the DataSource, ValueMember and DisplayMember properties of the derived
Label before bind the Text property of the control to a data source.

Public Class MyLabel
Inherits Label

Private _datasource As IList
Private _valuemember As String
Private _displaymember As String

Public Property DataSource() As IList
Get
Return _datasource
End Get
Set(ByVal value As IList)
_datasource = value
End Set
End Property

Public Property ValueMember() As String
Get
Return _valuemember
End Get
Set(ByVal value As String)
_valuemember = value
End Set
End Property

Public Property DisplayMember() As String
Get
Return _displaymember
End Get
Set(ByVal value As String)
_displaymember = value
End Set
End Property

Sub New()
AddHandler Me.DataBindings.CollectionChanged, AddressOf
DataBindings_CollectionChanged
End Sub

Private Sub DataBindings_CollectionChanged(ByVal sender As Object,
ByVal e As System.ComponentModel.CollectionChangeEventArgs)
Dim b As Binding = CType(e.Element, Binding)
If (Not (b Is Nothing)) Then
If (b.PropertyName = "Text") Then
If (e.Action = CollectionChangeAction.Add) Then
AddHandler b.Format, AddressOf b_Format
b.ReadValue()
ElseIf (e.Action = CollectionChangeAction.Remove) Then
RemoveHandler b.Format, AddressOf b_Format
End If
End If
End If
End Sub

Private Sub b_Format(ByVal sender As Object, ByVal e As
ConvertEventArgs)
If (Not (_datasource Is Nothing) And _datasource.Count 0) Then
Dim pdc As PropertyDescriptorCollection =
TypeDescriptor.GetProperties(_datasource(0))
For i As Integer = 0 To _datasource.Count - 1
If (pdc(_valuemember).GetValue(_datasource(i)).ToStri ng() =
e.Value.ToString()) Then
e.Value = pdc(_displaymember).GetValue(_datasource(i))
Exit For
End If
Next
Else
Throw New Exception("Please set the DataSource, DisplayMember
and ValueMember properties first")
End If
End Sub

End Class

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 6 '07 #5

P: n/a
Linda,

That was my first thought too, but is this not a little bit long solution
while you have direct the result by filling the itemarray?

:-)

Cor

Nov 6 '07 #6

P: n/a
Hi Linda,
I was able to accomplish what I wanted by using the Format event. As a
learnig exercise for myself, I am going to try the custom control aproach
that you have suggested here. I have never done this before and have a few
general questions for you. I realize I could just add the code you have
given me here as a new class in the project and then reference it through
code in my form. What approach do I take to make it available to other
projects? Should I build a seperate project for it? If so, is it a class
library or a windows control project? How would I get it available in the
toolbox so that I can drop and position it on my form? Maybe you could point
me to something I could read.
Thanks for all your help!
--
Terry
"Linda Liu[MSFT]" wrote:
Hi Terry,

If we could custom draw the input box part of a ComboBox as well as its
items in the drop down list, a possible workaround may be custom drawing
the ComboBox to get what you want.

Unfortunately, we can not custom draw the input box part of a ComboBox.

IMO, the solution to use the Binding class's Format event to look up the
description youself you have mentioned in your first reply is good. In
addition, I think it would be better to create a custom control to
encapsulate the above logic. Then you could use this custom control
wherever you want.

The following is a sample of this custom control. Note that you shoud set
the DataSource, ValueMember and DisplayMember properties of the derived
Label before bind the Text property of the control to a data source.

Public Class MyLabel
Inherits Label

Private _datasource As IList
Private _valuemember As String
Private _displaymember As String

Public Property DataSource() As IList
Get
Return _datasource
End Get
Set(ByVal value As IList)
_datasource = value
End Set
End Property

Public Property ValueMember() As String
Get
Return _valuemember
End Get
Set(ByVal value As String)
_valuemember = value
End Set
End Property

Public Property DisplayMember() As String
Get
Return _displaymember
End Get
Set(ByVal value As String)
_displaymember = value
End Set
End Property

Sub New()
AddHandler Me.DataBindings.CollectionChanged, AddressOf
DataBindings_CollectionChanged
End Sub

Private Sub DataBindings_CollectionChanged(ByVal sender As Object,
ByVal e As System.ComponentModel.CollectionChangeEventArgs)
Dim b As Binding = CType(e.Element, Binding)
If (Not (b Is Nothing)) Then
If (b.PropertyName = "Text") Then
If (e.Action = CollectionChangeAction.Add) Then
AddHandler b.Format, AddressOf b_Format
b.ReadValue()
ElseIf (e.Action = CollectionChangeAction.Remove) Then
RemoveHandler b.Format, AddressOf b_Format
End If
End If
End If
End Sub

Private Sub b_Format(ByVal sender As Object, ByVal e As
ConvertEventArgs)
If (Not (_datasource Is Nothing) And _datasource.Count 0) Then
Dim pdc As PropertyDescriptorCollection =
TypeDescriptor.GetProperties(_datasource(0))
For i As Integer = 0 To _datasource.Count - 1
If (pdc(_valuemember).GetValue(_datasource(i)).ToStri ng() =
e.Value.ToString()) Then
e.Value = pdc(_displaymember).GetValue(_datasource(i))
Exit For
End If
Next
Else
Throw New Exception("Please set the DataSource, DisplayMember
and ValueMember properties first")
End If
End Sub

End Class

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 8 '07 #7

P: n/a
Hi Terry,

About your first question, you could add some attributes on the DataSource,
DisplayMember and ValueMember properties of the custom control to make the
design time behavior of these three properties like that of the DataSource,
DisplayMember and ValueMember properties of a ComboBox.

The following is a sample:

Imports System.Drawing.Design

Public Class MyLabel
Inherits Label
<DefaultValue(CType(Nothing, String)),
AttributeProvider(GetType(IListSource))_
Public Property DataSource() As IList
...
End Property

<Editor("System.Windows.Forms.Design.DataMemberFie ldEditor,
System.Design, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a", _
GetType(UITypeEditor)), DefaultValue("")_
Public Property ValueMember() As String
...
End Property

<DefaultValue(""), _
TypeConverter("System.Windows.Forms.Design.DataMem berFieldConverter,
System.Design, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"),
Editor("System.Windows.Forms.Design.DataMemberFiel dEditor, System.Design,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
GetType(UITypeEditor))_
Public Property DisplayMember() As String
...
End Property
...
End Class

Build the project and open the form containing the custom control in the
designer. Select the custom control on the form and go to the DataSource
entry in the Properties window, a drop down arrow should appear on the
right hand. If you click it, a drop down window should open with all data
sources available in the project listed in it. Then go to the DisplayMember
or ValueMember entry in the Properties window and click the drop down arrow
on the right, and you should see a drop down window opening with all
properites available in the selected data source.

About your second question, are all the objects in the data source of the
same type? If the problem is still not solved, please send me a simple
project that could just reproduce the problem. To get my actual email
address, remove 'online' from my displayed email address.

Sincerely,
Linda Liu
Microsoft Online Community Support

Nov 21 '07 #8

P: n/a
Hi Terry,

Thank you for your reply!

I understand your second question now.

Firstly, the reason why " Nothing = "" " returns true is that string
comparisons treat Nothing as "" (an empty string).

Secondly, it seems that the internal implementation of the ComboBox regards
Nothing equal to DBNull.Value.

So we can modify the code in the b_Format method in the derived Label class
as follows to get the same behavior of the ComboBox:

Public Class MyLabel
Inherits Label
...
Private Sub b_Format(ByVal sender As Object, ByVal e As ConvertEventArgs)
If (Not (_datasource Is Nothing) And _datasource.Count 0) Then
Dim pdc As PropertyDescriptorCollection =
TypeDescriptor.GetProperties(_datasource(0))
For i As Integer = 0 To _datasource.Count - 1
Dim valueinDS As Object =
pdc(_valuemember).GetValue(_datasource(i))
If ((valueinDS Is Nothing Or valueinDS Is DBNull.Value) And
(e.Value Is Nothing Or e.Value Is DBNull.Value)) Then
e.Value = pdc(_displaymember).GetValue(_datasource(i))
Exit For
ElseIf (valueinDS IsNot Nothing And valueinDS IsNot
DBNull.Value And e.Value IsNot Nothing And e.Value IsNot DBNull.Value) Then
If (valueinDS.ToString() = e.Value.ToString()) Then
e.Value =
pdc(_displaymember).GetValue(_datasource(i))
Exit For
End If
End If
Next
Else
Throw New Exception("Please set the DataSource, DisplayMember
and ValueMember properties first")
End If
End Sub

End Class

Please try it in your project to see if it solves the problem and let me
know the result.

Sincerely,
Linda Liu
Microsoft Online Community Support

Nov 22 '07 #9

P: n/a
Hi Linda,
Thanks! Works like a charm! I did make one small change, which I will
share...
If (Not (_datasource Is Nothing) AndAlso _datasource.Count 0) Then
| so the second half
wont be evaluated if nothing

If you are in the US - Happy Thanksgiving! If not, and in any case - Have a
Great Day and thanks again for all your help!

--
Terry
"Linda Liu[MSFT]" wrote:
Hi Terry,

Thank you for your reply!

I understand your second question now.

Firstly, the reason why " Nothing = "" " returns true is that string
comparisons treat Nothing as "" (an empty string).

Secondly, it seems that the internal implementation of the ComboBox regards
Nothing equal to DBNull.Value.

So we can modify the code in the b_Format method in the derived Label class
as follows to get the same behavior of the ComboBox:

Public Class MyLabel
Inherits Label
...
Private Sub b_Format(ByVal sender As Object, ByVal e As ConvertEventArgs)
If (Not (_datasource Is Nothing) And _datasource.Count 0) Then
Dim pdc As PropertyDescriptorCollection =
TypeDescriptor.GetProperties(_datasource(0))
For i As Integer = 0 To _datasource.Count - 1
Dim valueinDS As Object =
pdc(_valuemember).GetValue(_datasource(i))
If ((valueinDS Is Nothing Or valueinDS Is DBNull.Value) And
(e.Value Is Nothing Or e.Value Is DBNull.Value)) Then
e.Value = pdc(_displaymember).GetValue(_datasource(i))
Exit For
ElseIf (valueinDS IsNot Nothing And valueinDS IsNot
DBNull.Value And e.Value IsNot Nothing And e.Value IsNot DBNull.Value) Then
If (valueinDS.ToString() = e.Value.ToString()) Then
e.Value =
pdc(_displaymember).GetValue(_datasource(i))
Exit For
End If
End If
Next
Else
Throw New Exception("Please set the DataSource, DisplayMember
and ValueMember properties first")
End If
End Sub

End Class

Please try it in your project to see if it solves the problem and let me
know the result.

Sincerely,
Linda Liu
Microsoft Online Community Support

Nov 22 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.