Using DataRelations and DevExpress Grids - Hide expansion control - vb.net

I have a bit of a weird issue. We use DevExpress controls to do all our Windows Form development. Anyway, I found a perfect use for the DataRow.SetParentRow/GetParentRow methods in my grid. So I created a DataRelation, added it to the DataSet and bound it as the data source for my grid. The issue is I now find this:
On my grid. It seems to be the DataRelation (when I mouse over it the tooltip is the DataRelation name).
Does anyone know how to hide this line of controls? If I cannot get rid of them I will have to write a parent/child link between the rows, and that would be a shame because the DataRelation stuff works almost perfectly.
Thanks in advance!

You want to set the following property to hide those: (this is for a grid view, banded grid view or advanced banded grid view)
In OptionsDetail set EnableMasterViewMode=False
If you have a master Detail grid that has times where the details are empty and you want to hide those you can do so by handling the custom draw for the masterview cells something like this:
Private Sub gvMain_CustomDrawCell(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs) Handles gvMain.CustomDrawCell
Dim View As DevExpress.XtraGrid.Views.Grid.GridView = CType(sender, DevExpress.XtraGrid.Views.Grid.GridView)
If e.Column.VisibleIndex = 0 And View.IsMasterRowEmpty(e.RowHandle) Then
CType(e.Cell, DevExpress.XtraGrid.Views.Grid.ViewInfo.GridCellInfo).CellButtonRect = Rectangle.Empty
End If
End Sub

Related

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.

re: behaviour of a UserControl in a designer and at runtime

I'm trying to create a StackPanel user control that would allow me to stack newly added controls in a vertical fashion (like a WPF StackPanel but using Windows forms).
I created a new user control with the core code shown below, but even though my Location gets asigned right values in designer I can pop message boxes, the designer view does not re-arange the child controls that I drag and drop onto my stack panel, also at runtime my location seems to be overwriten with what the designer thinks is right (a Location of where I placed the control)
Public Class StackPanel
Inherits Panel
Private biasHeight As Integer = 0
Private Sub StackPanel_ControlAdded(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles MyBase.ControlAdded
Dim newControl As System.Windows.Forms.Control = e.Control
'
' NOT WORKING: Set location of the newly added control in a panel and at runtime
'
newControl.Location = New System.Drawing.Point(0, biasHeight)
'
' Store the y-cooridnate of the next control
'
biasHeight = biasHeight + newControl.Height
End Sub
End Class
Typically these kind of things will be done by implementing the custom LayoutEngine. Msdn has a sample as well.
Am not sure why your code doesn't work, no reason to go behind it because it is terribly flawed. You are just setting the Location only when adding new control. There are lot more. You need to consider when a control is removed, when some control is hidden(visible set to false), When Size changed, When Padding changed etc etc.
So, Instead of reinventing the wheel I suggest you to use FlowLayoutPanel. If at all you want to implement it yourself then do it right. I mean create your LayoutEngine as shown in the provided link. In fact that link do have what you need.

What is the best practice when you want to modify a form

I am modifying an application and I need to add and remove field depending on the configuration the user set.
Right now, I use two panel that contain the corresponding field and I'm hiding and showing them when I need to. I re-size the form and relocate elements in the form accordingly. But then, it become hard to modify either of the panel and the form when you are in editing mode.
I also think that since it re-use a lot of the element, it would be unwise to create another separate form but maybe it's just me.
I'm not sure how to rearrange all of this and would really like some tips.
It seems like you are trying to adjust the form size depending on different controls. I suggest you learn about TableLayoutPanels. For each TableLayoutPanel Row/Column, you can set that Row/Column to AutoSize.
This means if there's nothing to display (aka it is hidden), your TableLayoutPanel will AutoSize accordingly.
Example
Your TableLayoutPanel is docked to the MainForm.
You have three rows in your TableLayoutPanel.
The first row will decide if we should hide or show the 2nd and 3rd rows.
Form1.vb [Design]
Using the following code, the TableLayoutPanel will adjust it's controls appropriately:
Private Sub RadioButton1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton1.CheckedChanged, RadioButton2.CheckedChanged
Select Case True
Case RadioButton1.Checked 'Show Row #2
Label1.Show()
Label2.Hide()
Case RadioButton2.Checked 'Show Row #3
Label1.Hide()
Label2.Show()
End Select
End Sub
Here's the result:
How Does it Work?
Almost everything was done by the designer.
Label1 was placed in your TableLayoutPanel's 2nd row (Index=1)
Label2 was placed in your TableLayoutPanel's 3rd row (Index=2)
Both labels were docked to "Fill" the row
The labels were then set to TextAlign=Center
The TableLayoutPanel's Row2 was set to "AutoSize"
The TableLayoutPanel's Row3 was set to "AutoSize"
Create two separate sets of controls in different forms. Then import them both as composite controls. You can then hide and show as needed using the .visible control property.

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.

Clean way to display/hide a bunch of buttons based on a ComboBox selection

I'm writing a standalone application in VB.NET using Visual Studio 2005.
I want to display/hide a bunch of Buttons based on the selected value of a ComboBox. Each selection would have a different set of Buttons to display, and I'd like to have them arranged in a nice grid.
Driving a TabControl with the ComboBox value would be the kind of behavior I want, but I don't want it to look like a TabControl to the user because it might be confusing.
Is there a way to do this?
Basically, I'd like Selection1 of the ComboBox to show Buttons 1-4, Selection2 to show Buttons 5-11, Selection3 to show (maybe) Buttons 1, 3, 5, 6, and 8, etc., have them arranged nicely, and have the GUI show only the ComboBox and the buttons.
Thanks in advance as always!
Use a Panel control (or multiple if the items aren't grouped right next to each other) and set the visibility accordingly.
(Added)
You CAN stack panels on top of each other, so that the buttons all look like they're in the same location. but it becomes a maintenance nightmare and I don't recommend it.,
Hack warning - the following is a hack, but it works.
Another option is to use a tab control, but hide the tab buttons. (You can do this by positioning a panel over the buttons, but you have to be careful of letting the user resize the form.) Then you set the TabIndex based on the drop-down changing.
Edit again - added per comment
If you use the hack, you can add this into the ComboBox's selected index changed event....
(code may be wrong, as I'm not at my dev pc and can't check, but you get the idea)
TabControl1.SelectedIndex = ComboBox1.SelectedIndex
You could put all of your buttons on a panel on your form. Then when the SelectedIndex event of the combobox fires, you can loop through the buttons on the panel and turn them on and off based on their Tag property.
For this example you would set the Tag property of each button equal to the combobox index or indexes that you want it to turn on for. If you want it visible for more than one combo selection just comma seperate the index values in the tag property.
You don't have to key off of the combobox index. You could use the selected text for example. If you did that, just put the texts to show the button for in the tag property and change the code from ComboBox1.SelectedIndex.ToString to ComboBox1.SelectedText.
The buttons will turn on and off where they are placed at design time, but you could add some code here to arrange them dynamically as well so that all the visible buttons are neatly arranged.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
For Each ctrl As Control In Me.Panel1.Controls
If TypeOf ctrl Is Button Then
If Array.IndexOf(Split(ctrl.Tag, ","), ComboBox1.SelectedIndex.ToString) > -1 Then
ctrl.Visible = True
Else
ctrl.Visible = False
End If
End If
Next
End Sub
Maybe using a FlowLayoutPanel will help you display the buttons.
You can use a jagged array to define which buttons belong to which combo-box item.