Tooltip display in VB.NET - vb.net

Using either the Designer properties or by programming it directly, I cannot seem to get a tool tip to display the way I thought I should be able when I hover over the control.
For instance, although I can display the text I want, no matter what I set as the AutoPopDelay (I want 30 seconds) or as the background color (I want a Yellow), the tool tip always comes up for the default 5 seconds on a gray background only.
Below is the sub that I programmed. What am I missing?:
Private Sub lblUploadFileTypeHelp_MouseHover(sender As Object, e As EventArgs) Handles lblUploadFileTypeHelp.MouseHover
ToolTip1.OwnerDraw = True
ToolTip1.IsBalloon = True
ToolTip1.BackColor = Color.LemonChiffon
ToolTip1.AutoPopDelay = 30000
ToolTip1.Show("Sample text to display", lblUploadFileTypeHelp)
End Sub

IsBalloon is being taken into consideration before OwnerDraw.
You would need to handle your own drawing to get a custom display.
Have a look at the MSDN code sample MSDN Tooltip

Related

How to hide a DataGridViewButtonCell

I have a DataGridViewButtonCell in my DataGridView and I wanted to set the property Visible to True.
I have tried:
DataGridView1.Rows("number of row i want").Cells("number of cell i want").Visible = True
Unfortunately it says that the property visible is read only.
Here is the code:
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
'does not work
DataGridView1.Rows(e.RowIndex).Cells(6).Visible = True
End Sub
Does anyone knows how I can achieve this?
Thanks.
There is no actual way to hide a DataGridViewButtonCell. Currently I can only see two options:
Use padding to move the button over as shown here. I will provide similar VB.NET code
Set the Cell to a DataGridViewTextBoxCell and set the ReadOnly property to True
Use Padding:
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If DataGridView1.Rows(e.RowIndex).Cells(6).GetType() Is GetType(DataGridViewButtonCell) Then
Dim columnWidth As Integer = DataGridView1.Columns(e.ColumnIndex).Width
Dim newDataGridViewCellStyle As New DataGridViewCellStyle With {.Padding = New Padding(columnWidth + 1, 0, 0, 0)}
DataGridView1.Rows(e.RowIndex).Cells(6).Style = newDataGridViewCellStyle
End If
End Sub
Use DataGridViewTextBoxCell:
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If DataGridView1.Rows(e.RowIndex).Cells(6).GetType() Is GetType(DataGridViewButtonCell) Then
Dim newDataGridViewCell As New DataGridViewTextBoxCell
DataGridView1.Rows(e.RowIndex).Cells(6) = newDataGridViewCell
newDataGridViewCell.ReadOnly = True
End If
End Sub
Both of these should give you the effect of not showing the button.
This is really a perspective issue. From a programmer’s perspective, simply ignoring the button clicks on the buttons I want to disable is very easy to do and takes just a few lines of code.
From a user perspective, this situation would play out like this… the user clicks what appears to be a valid enabled button, and nothing happens. The user did not write the code for this… so at best the user will think the computer is not responding to the button click or at the worst… would think your coding skills are dubious!
The same situation happens if the button is missing. The user is not going to know why it is missing… but will most likely come to the same conclusion described above with a non-working button.
In another very simple approach, let say that all the buttons are enabled and we have a list of the button indexes we want to disable. The users presses one of the buttons, we check the disabled button list and if the clicked button is one that is disabled, simply display a message box to indicate why this button is disabled. This approach says to the user… “Here are a bunch of buttons, guess which ones are enabled”…
The DataGridViewDisableButtonCell and DataGridViewDisableButtonColumn wrappers solve all of the above issues… the button is visible so the user wont question where the button went if you set it to invisible and it is greyed out. “Greyed out” is something most users understand and will relieve the user of having to “guess” which buttons are enabled.
You can create a wrapper for two classes: the DataGridViewButtonCell and the DataGridViewButtonColumn.
The link How to: Disable Buttons in a Button Column in the Windows Forms DataGridView Control to the MS example is one I have used before using C#, however there is a VB implementation at the link also.
Below is a picture of the result of using the two wrappers described in the MS link. For testing, the picture below uses the check boxes to left of the button to disable the button on the right.
IMHO, using this strategy is user friendly. If you simply make the button invisible or read only, then the user is possibly going to think your code is messed up and not have a clear understanding of WHY the button is missing or doesn’t work. A disabled button indicates to the user that the button is not available for that item. An option would be to have a mouse roll-over indicating why the button is disabled.

Show Continuous Progress Bar on DataGridView Fill

I have two forms (Main.vb and Schedule.vb). Main has a toolstripmenu and a panel. When "View Schedule" is selected from the toolstripmenu, the Schedule form is opened within the Main form's panel. So it opens as a "sub form". This works perfectly.
Private Sub tsmiScheduleView_Click(sender As Object, e As EventArgs) Handles tsmiScheduleView.Click
Schedule.TopLevel = False
Schedule.Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right
Schedule.Size = New Size(pnlMain.Width, pnlMain.Height) 'anchors will be disrupted if form does not open to fit with main
Me.pnlMain.Controls.Add(Schedule)
Schedule.Show()
End Sub
The problem happens in Schedule.vb, there is a DataGridView there that gets populated via a TableAdapter. But it takes a long time to load. So I want to show a Continuous Progress Bar while the DataGridView is loading.
Private Sub Schedule_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Load main data into the Schedule DataGridView
Me.SchedulViewTable_TableAdapter.Fill(Me.DataSetSchedule.SchedulViewTable)
End Sub
I can get the progress bar to show easy enough, but it freezes when the DataGridView is loading.
I've tried using threads, backgroundworkers, putting the ProgressBar in a seperate form and displaying it from there, and I even nixed my ProgressBar idea for an animated gif using picture boxes. None of these are working for me. Can anyone help?
As a note, I would love to use this all over my program. Whenever I run into something that's going to take time I'd like to have an easy way to say: "Okay, display the Continuous Progress Bar on Main.vb until I'm done".
Thanks.
Set the DataGridView DataSource to null before executing the Fill command.
Then set the DataSource back to DataTable.
If you do that, how long does it take between the binding and the display (I would bet on 5 to 15 seconds)?
It seem like the only thing to do is load less rows into the DataGridView so there is no need for a progress bar. Not what I wanted to do but there isn't a way to do what I originally wanted.
I was able to show text, "Loading..." but no animation.

Cut status strip label to width of form

I have a form with a status strip, which contains a progress bar an a label. Both of these are used to show the user the status/progress of several background workers.
My problem is that sometimes the label is longer than the form is wide (it contains Parameter names that vary quite widely in length). The form has a constant width and is not re-sizable by the user. When this issue occurs the label just appears as blank, I would instead like to cut the label to the length of the form and concatenate "..." on the end.
Can anyone give me some advise on where to start with this? i have tried Google and SO searches and have been unable to come up with anything similar. I essentially need to find the length of the string as it will display on the form, but I don't know where to start with that.
First thing to do is to change the StatusStrip.LayoutStyle from Table to Flow. Which will prevent the label from disappearing. Next, you still want the user to have a chance to read the full text of the label even though it is truncated. Set the StatusStrip.ShowItemToolTips property to True and the label's AutoToolTip to True.
Getting the label's text to not overlap the grip is an uglier problem to fix but one you don't have since you made your form un-resizable. Set the form's SizeGripStyle property to Hide.
This will fix your problem, no code required.
You can try something like this:
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
If Label1.Text.Length > iMaxLblLenght Then
Label1.Text = Label1.Text.Substring(0, iMaxLblLenght) & "..."
End If
End Sub

Toggling panel visibility isn't working when they are stacked

I have a form that has two views. These views are controlled by radio buttons on top of the form.
Here is the program:
http://dl.dropbox.com/u/41629841/DataCalculator/DataCalc1.PNG
Notice how the Radio button for Number Converter is selected.
Here is what it looks like when you select the Text Converter radio button:
http://dl.dropbox.com/u/41629841/DataCalculator/DataCalc2.PNG
That isn't right. I have it set to hide the panel containing the number converter and show the one containing the text converter when you click that one. It hides the number converter but doesn't show the text converter.
Here is a picture of the text converter panel:
http://dl.dropbox.com/u/41629841/DataCalculator/DataCalc4.PNG
Here is the relevant code:
Private Sub frmCalculator_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
rdoNumberConverter.Checked = True
End Sub
Private Sub rdoTextConverter_Click(sender As Object, e As System.EventArgs) Handles rdoTextConverter.Click
pnlTextConverter.Visible = True
pnlNumberConverter.Visible = False
End Sub
Private Sub rdoNumberConverter_Click(sender As Object, e As System.EventArgs) Handles rdoNumberConverter.Click
pnlNumberConverter.Visible = True
pnlTextConverter.Visible = False
End Sub
Everything seems right and I can't figure out why the text converter doesn't show up. I've determined that it has something to do with the fact that both of the panels are right on top of each other because when I move them apart, the visibility toggling works perfectly.
Here are the supporting pictures:
http://dl.dropbox.com/u/41629841/DataCalculator/DataCalc5.PNG
http://dl.dropbox.com/u/41629841/DataCalculator/DataCalc6.PNG
So how do I make it work when they are on top of each other?
I tried using BringToFront() and SendToBack() to make sure the visible panel is in the front and it didn't make a difference.
Make sure the TextConverter panel isn't "inside" the NumberConverter panel.
From the designer, move them into different places so that they do not overlap at all.
Then in code, move them into place:
textConverterPanel.Location = numConvertPanel.Location
Your visible, not visible toggling should work then.
The issue is the panels becoming embedded, as pointed out by #LarsTech. This occurs if you use the GUI to move them to the same location.
If you want to overlap them at design time, create the second panel in a different location. Then in the Properties of the panel in the final location, copy the Location, and paste it into the Location property of the second panel. This will move it to the proper location in the Designer without embedding one into another. This can be repeated for as many additional panels as needed.

How do I color CheckedListBox items in VB.NET?

I am making a personal application in VB.NET that uses a CheckedListBox to store items. I have three buttons on my form, with which I would like to change the selected item's color with (to green, orange, and red.)
I have tried numerous approaches to this issue and have had no such luck. Could someone lend a helping hand?
Use a ListView instead. It has support for checkboxes and selected item colors.
There is a very similar answer here:
For each <item> in CheckedListBox. <item> returns as Object and not as Control
Basically, this control won't do what you want it to (at least not without much complexity). You need to upgrade your control to a ListView.
You can also use TreeView that looks and acts like a checked list box:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.TreeView1.ShowLines = False
Me.TreeView1.CheckBoxes = True
Dim MyColors() As Color = {Color.Black, Color.Blue, Color.Red, Color.Green, Color.Aqua}
For x As Integer = 0 To 4
Dim NewNode As TreeNode = Me.TreeView1.Nodes.Add("Node" & x)
NewNode.ForeColor = MyColors(x)
Next
End Sub
Took the advice of using a ListView. Looked and worked great on my Windows 7 and Vista boxes but on XP, the ListView did not display properly (items were crunched overtop of one another, checkboxes didn't always display). Checked to make sure it was not a framework version issue and that it was not a screen resolution issue. Ended up retreating back to the CheckedListBox implementation which did NOT have the inconsistency.
Found this solution that accomplished the removal of the blue highlight in the CheckedListBox scenario for me. Using it however you have to keep track of the selection in another manner (global variable, looking at the checked item(s), etc.).
I simply clear the selected item(s) after processing the "..._SelectedIndexChanged". The first thing I do in the "..._SelectedIndexChange" is test for no Selection and do nothing if that is the change. The result is that the currently selected item appears unselected (and actually is unselected, i.e. no blue highlight) however the CheckBox remains checked indicating the most recent selection for the user.
Example ==>
Private Sub ModelCheckedListBox_SelectedIndexChanged(ByVal sender As System.Object,...
Dim x As Short = ModelCheckedListBox.SelectedIndex
If x >= 0 Then
'Something I always do since the Selection Mode = "One" doesn't bother to clear
'the checks itself
ModelCheckedListBox.SetItemChecked(x, True)
If ModelCheckedListBox.CheckedItems.Count > 1 Then
For Each item In ModelCheckedListBox.CheckedIndices
If item <> x Then
ModelCheckedListBox.SetItemChecked(item, False)
End If
Next
End If
ModelCheckedListBox.Refresh()
'More of your code
ModelCheckedListBox.ClearSelected()
End If
End Sub