Can VBA Forms have a Flow Layout? - winforms

I'm guessing this is impossible, but here goes.
Java and more recent .Net updates are capable of a Flow Layout - where a layout manager re-arranges the form controls to fit in the available space.
I've only seen VBA & WinForms using hard-coded absolute positions.
Has anyone encountered a flow-layout manager in this context?

Access 2007 and later versions implement this functionality via anchoring: Make controls stretch, shrink, or move as you resize a form
If you want to do it in earlier versions you can roll your own using the On Resize event of the form.

I have a form which is laid out like this. All of my controls are sequentially named based on their vertical position: txt_R1, txt_R2, txt_R3 etc...
When the Form loads, it looks like this:
When I update the combo box, the code below executes:
Dim s_tier As String
Dim s_rate As String
Dim s_lbl_Rate As String
Dim s_lbl_Tier As String
Dim s_obj As String
Me.TXT_Min.Visible = True
Me.LBL_MIN.Visible = True
Me.TXT_Min.Value = 0
Me.TXT_Scale.Visible = True
Me.lbl_Scale.Visible = True
Me.TXT_Scale.Value = 0
Me.txt_MinMax.Visible = True
Me.lbl_MinMax.Visible = True
Me.txt_MinMax.Value = 0
s_tier = "TXT_T"
s_rate = "TXT_R"
s_lbl_Rate = "LBL_R"
s_lbl_Tier = "LBL_T"
For i = 1 To numActive
'Tier Text Box
s_obj = s_tier & i
Me(s_obj).Visible = True
Me(s_obj).Value = "NULL"
'Tier Label
s_obj = s_lbl_Tier & i
Me(s_obj).Visible = True
'Rate Text Box
s_obj = s_rate & i
Me(s_obj).Visible = True
Me(s_obj).Value = "NULL"
'Rate Label
s_obj = s_lbl_Rate & i
Me(s_obj).Visible = True
Next i
'set last tier to infinite, since last tier typically goes on forever
s_obj = s_tier & numActive
Me(s_obj).Value = ChrW(&H221E)
Me(s_obj).FontSize = 16
'Make Test button visible and move to appropriate place
s_obj = s_lbl_Tier & (numActive + 1)
Me.Btn_Test.Top = Me(s_obj).Top
Me.Btn_Test.Left = Me(s_obj).Left
Me.Btn_Test.Visible = True
s_obj = s_tier & (numActive + 1)
'Make Test button visible and move to appropriate place
Me.btn_SQL.Top = Me(s_obj).Top
Me.btn_SQL.Left = Me(s_obj).Left
Me.btn_SQL.Visible = True
Me.Refresh
The refreshed form now looks like this if "1" is selected in the combo box:
... Or if "2" is selected in the combo box:
... Or if "3" is selected in the combo box:
The key to my method is to use the sequential naming convention as a way to exploit the
for i = 1 to numactive
piece of code. Once the loop ends, all of the static controls are visible. I can add 1 the numactive variable to determine where the first invisible control is, and anchor my 'floating' controls to that position.
This method can be tweaked to actually place any control into any position using offsets instead of the position of other controls. Let your imagination run wild!

WinForms of course has the FlowLayoutPanel and TableLayoutPanel..
There's an example of AutoLayout for Winforms on MSDN.

Related

Windows Form Label position issue

I have a UserControl which has a Label at the bottom right corner defined as followed:
this.lblInspectionName.AutoSize = true;
this.lblInspectionName.Font = new System.Drawing.Font("Segoe UI", 10.25F, System.Drawing.FontStyle.Bold);
this.lblInspectionName.Location = new System.Drawing.Point(3, 7);
this.lblInspectionName.Name = "lblInspectionName";
this.lblInspectionName.Size = new System.Drawing.Size(113, 19);
this.lblInspectionName.TabIndex = 0;
this.lblInspectionName.Text = "___";
Its Text content changes based on other events. The problem is that when the Label gets bigger, it goes to left (as I want otherwise it exceeds the right border), but when it gets smaller again the location is the same as the previous case and it's positioned too left.
Do you know how I can let the label grows to left when necessary keeping always a certain distance/margin to the right border? Thanks in advance!
EDIT
Doing as suggested, the situation is the following:
I would add these properties settings
this.lblInspectionName.Dock = DockStyle.Bottom;
this.lblInspectionName.TextAlign = ContentAlignment.BottomRight;
But you need to set the AutoSize back to false.
// Comment out this line. False is default
// this.lblInspectionName.AutoSize = true;

How can I add text to a Checkbox I create using iTextSharp?

Derived from Jeff S's methodology found here, I can add a "Checkbox" to a PDF page like so:
PdfPTable tblFirstRow = new PdfPTable(5);
tblFirstRow.SpacingBefore = 4f;
tblFirstRow.HorizontalAlignment = Element.ALIGN_LEFT;
. . . // code where textboxes are added has been elided for brevity
PdfPCell cell204Submitted = new PdfPCell()
{
CellEvent = new DynamicCheckbox("checkbox204Submitted", "204 Submitted or on file")
};
tblFirstRow.AddCell(cell204Submitted);
doc.Add(tblFirstRow);
The DynamicCheckbox class, based on Jeff S's CustomCellLayout class, is:
public class DynamicCheckbox : IPdfPCellEvent
{
private string fieldname;
private string cap;
public DynamicCheckbox(string name, String caption)
{
fieldname = name;
cap = caption;
}
public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
{
PdfWriter writer = canvases[0].PdfWriter;
RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
ckbx.CheckType = RadioCheckField.TYPE_CHECK;
ckbx.Text = cap;
PdfFormField field = ckbx.CheckField;
writer.AddAnnotation(field);
}
}
My problem is that the checkbox's text (the string assigned to ckbx.Text) is not displaying. The checkbox (outsized) occupies the last cell in the table row, but there is no (visible) accompanying text.
What's missing from my code?
Note: I tried to reduce the size of the checkbox by doing this:
Rectangle tangle = new Rectangle(20, 20);
//RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
RadioCheckField ckbx = new RadioCheckField(writer, tangle, fieldname, "Yes");
...but that attempt failed - with that code, I can't even "find" the checkbox in the generated PDF file - clicking willy-nilly in column 5 conjures up no checkbox...
Others have answered the label part. The Rectangle that you have called "tangle" needs to be calculated off of the rectangle that comes into the event handler, similar to
Rectangle tangle = new Rectangle(
rectangle.Left,
rectangle.Top - PDFStyle.boxsize - 4.5f,
rectangle.Left + PDFStyle.boxsize,
rectangle.Top - 4.5f
);
Where PDFStyle.boxsize is the width/height of the checkbox and 4.5f is the padding the edge of the cell. Basically the rectangle isn't relative to the cell, but absolute to the page.
As described in ISO-32000-1, a check box is a field of type Button. If you define text for a button, you want to define the text that is displayed on the button. However: in the case of a check box, there is no such text! Instead, you have two appearances, one for the Off value and one for the Yes value.
An educated guess made by an attentive reader would be that you don't want to add text (to the button), but that you want to add a label (for a checkbox). Again you should consult ISO-32000-1 and you'll discover that the spec doesn't say anything about labels for check boxes. The concept just doesn't exist at the level of an AcroForm.
This doesn't mean the concept doesn't exist in general. Many PDF tools allow you to define check boxes that are preceded by a label. When you look inside the PDF, you'll discover that this label is just part of the content, whereas the check box is represented by a widget orientation.
Let's take a look at the official documentation instead of frustrating ourselves searching on every place of the web except on the official web site. More specifically: let's take a look at the Buttons example from Chapter 7 of my book. You'll see that one can set text for a real button:
PushbuttonField button = new PushbuttonField(writer, rect, "Buttons");
button.setText("Push me");
This isn't possible with check boxes (for the obvious reason that the appearance of a check box is completely different). If we want to add a label, we can add it for instance like this:
checkbox = new RadioCheckField(writer, rect, LANGUAGES[i], "Yes");
field = checkbox.getCheckField();
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", onOff[0]);
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Yes", onOff[1]);
writer.addAnnotation(field);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
new Phrase(LANGUAGES[i], font), 210, 790 - i * 40, 0);
You can find the C# version of these examples here: http://tinyurl.com/itextsharpIIA2C07
Creating a checkbox, and then accompanying text to its right, can be done like this:
PdfPCell cell204Submitted = new PdfPCell()
{
CellEvent = new DynamicCheckbox("checkbox204Submitted")
};
tblFirstRow.AddCell(cell204Submitted);
// . . . Chunks and an anchor created; that code has been elided for brevity
Paragraph parCkbxText = new Paragraph();
parCkbxText.Add(Chunk204SubmittedPreamble);
parCkbxText.Add(ChunkBoldNote);
parCkbxText.Add(Chunk204Midsection);
parCkbxText.Add(anchorPayeeSetup204);
PdfPCell cellCkbxText = new PdfPCell(parCkbxText);
cellCkbxText.BorderWidth = PdfPCell.NO_BORDER;
tblFirstRow.AddCell(cellCkbxText);
public class DynamicCheckbox : IPdfPCellEvent
{
private string fieldname;
public DynamicCheckbox(string name)
{
fieldname = name;
}
public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
{
PdfWriter writer = canvases[0].PdfWriter;
RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
ckbx.CheckType = RadioCheckField.TYPE_CHECK;
ckbx.BackgroundColor = BaseColor.ORANGE;
ckbx.FontSize = 6;
ckbx.TextColor = BaseColor.WHITE;
PdfFormField field = ckbx.CheckField;
writer.AddAnnotation(field);
}
}

Create DataGrid in WPF at runtime

There is a DataGridView which is created at runtime with data fetching from database. There are four types of columns in data grid view:
DataGridViewTextBoxColumn
DataGridViewComboboxColumn
DataGridViewButtonColumn
DataGridViewCheckBoxColumn
Code for creating that datagridview is as below:
_form.DGV_.AutoGenerateColumns = False
_form.DGV_.Columns.Clear()
'Required Variables
Dim pom_DataGridViewTextBoxColumn As DataGridViewTextBoxColumn = Nothing
Dim pom_DataGridViewComboBoxColumn As DataGridViewComboBoxColumn = Nothing
Dim pom_DataGridViewButtonColumn As DataGridViewButtonColumn = Nothing
Dim pom_DataGridViewCheckBoxColumn As DataGridViewCheckBoxColumn = Nothing
'Column-1 (ID: jntDate)
pom_DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
pom_DataGridViewTextBoxColumn.DataPropertyName = "jntDate"
pom_DataGridViewTextBoxColumn.HeaderText = "Date"
pom_DataGridViewTextBoxColumn.DefaultCellStyle.Format = "d"
_form.DGV_.Columns.Add(pom_DataGridViewTextBoxColumn)
'Column-2 (ID: jntAcc)
pom_DataGridViewComboBoxColumn = New DataGridViewComboBoxColumn
pom_DataGridViewComboBoxColumn.DataPropertyName = "jntAcc"
'Cond: If dataset Acc does not contain any table then add table from database.
If Acc.Tables.Count > 0 Then
pom_DataGridViewComboBoxColumn.DataSource = Acc.Tables.Item(0)
Else
Acc.Tables.Add(Tbl_Select("SELECT *, accNo AS byNo, accName as byName FROM tblAccounts", False, ""))
pom_DataGridViewComboBoxColumn.DataSource = Acc.Tables.Item(0)
End If
'Cond: If _Account_Name_Number is True then set DisplayMember property to 'byName'.
If _Account_Name_Number Then
pom_DataGridViewComboBoxColumn.DisplayMember = "byName"
Else
pom_DataGridViewComboBoxColumn.DisplayMember = "byNo"
End If
pom_DataGridViewComboBoxColumn.ValueMember = "accID"
pom_DataGridViewComboBoxColumn.HeaderText = "Account"
_form.DGV_.Columns.Add(pom_DataGridViewComboBoxColumn)
'Column-3 (ID: xxxx)
pom_DataGridViewButtonColumn = New DataGridViewButtonColumn
pom_DataGridViewButtonColumn.DataPropertyName = "xxxx"
pom_DataGridViewButtonColumn.UseColumnTextForButtonValue = True
pom_DataGridViewButtonColumn.HeaderText = "X"
pom_DataGridViewButtonColumn.Text = "X"
pom_DataGridViewButtonColumn.Width = 32
pom_DataGridViewButtonColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
pom_DataGridViewButtonColumn.DefaultCellStyle.ApplyStyle(pom_DataGridViewButtonColumn.DefaultCellStyle)
_form.DGV_.Columns.Add(pom_DataGridViewButtonColumn)
'Column-4 (ID: jntReview)
pom_DataGridViewCheckBoxColumn = New DataGridViewCheckBoxColumn
pom_DataGridViewCheckBoxColumn.DataPropertyName = "jntReview"
pom_DataGridViewCheckBoxColumn.HeaderText = "Review"
pom_DataGridViewCheckBoxColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
pom_DataGridViewCheckBoxColumn.DefaultCellStyle.ApplyStyle(pom_DataGridViewCheckBoxColumn.DefaultCellStyle)
_form.DGV_.Columns.Add(pom_DataGridViewCheckBoxColumn)
In WPF application, there is a need to populate same DataGrid with these four columns.
How can I create and bind data to four types of columns in DataGrid in WPF ?
Why not skip doing all that stuff in cs code? You'll start pinning yourself in the corner and WILL hit the wall when the datagrid will need more complex templates, data triggers, custom styles, animations, etc... Besides, it will make it easier not only on the next person, but you as well. When you have to add/fix something in the beast you create in .cs code 3-6 months down the road, it might take you quite a while to understand what is going on :)
Instead, do all your work in xaml, Create a UserControl, put this datagrid in it, Pass the DataContext from various instances of the UserControl down to it's DataGrid.

DataGridViewComboBoxCell Value Not Updating When Set Programmatically C# Winforms

I've read all the similiar posts about this darn control (DataGridViewComboBoxCell) and setting it's value programmatically but implementing all the suggestions hasn't worked. I could probably change the UI to get around this problem but I don't like to be beat!
private void PopulateAreaForRoleAssociation()
{
// If businessRoleList is null then no data has been bound to the dgv so return
if (businessRoleList == null)
return;
// Ensure businessArea repository is instantiated
if (businessAreaRepository == null)
businessAreaRepository = new BusinessAreaRespository();
// Get a reference to the combobox column of the dgv
DataGridViewComboBoxColumn comboBoxBusinessAreaColumn = (DataGridViewComboBoxColumn)dgvBusinessRole.Columns["BusinessArea"];
// Set Datasource properties to fill combobox
comboBoxBusinessAreaColumn.DisplayMember = "Name";
comboBoxBusinessAreaColumn.ValueMember = "Id";
comboBoxBusinessAreaColumn.ValueType = typeof(Guid);
// Fill combobox with businessarea objects from list out of repository
comboBoxBusinessAreaColumn.DataSource = businessAreaRepository.GetAll();
// loop through the businessRoles list which the dgv is bound to and get out each dgv row based upon the current id in the loop
businessRoleList.Cast<BusinessRole>().ToList().ForEach(delegate(BusinessRole currentRole)
{
DataGridViewRow currentRowForRole = dgvBusinessRole.Rows.Cast<DataGridViewRow>().ToList().Find(row => ((BusinessRole)row.DataBoundItem).Id == currentRole.Id);
// Get a reference to the comboBox cell in the current row
DataGridViewComboBoxCell comboBoxCell = (DataGridViewComboBoxCell)currentRowForRole.Cells[2];
// Not sure if this is necessary since these properties should be inherited from the combobox column properties
comboBoxCell.DisplayMember = "Name";
comboBoxCell.ValueMember = "Id";
comboBoxCell.ValueType = typeof(Guid);
// Get the business area for the current business role
BusinessArea currentAreaForRole = businessAreaRepository.FetchByRoleId(currentRole.Id);
// if the role has an associated area then set the value of the cell to be the appropriate item in the combobox
// and update the cell value
if (currentAreaForRole != null)
{
foreach (BusinessArea area in comboBoxCell.Items)
{
if (currentAreaForRole.Id == area.Id)
{
comboBoxCell.Value = area.Id;
dgvBusinessRole.UpdateCellValue(2, comboBoxCell.RowIndex);
}
}
}
});
}
The dgv is first bound to a binding list holding BusinessRole objects, then the combobox column is bound to a basic list of BusinessArea objects that come out of a repository class. I then loop through the bindinglist and pull out the row of the dgv that is bound to the current item in the bindinglist loop.
With that row I make a database call to see if the BusinessRole entity is associated with a BusinessArea entity. If it is then I want to select the item in the combobox column that holds the BusinessAreas.
The problem is that when the grid is loaded, all the data is there and the comboboxes are populated with a list of available areas, however any values that are set are not displayed. The code that sets the value is definately getting hit and the value I am setting definately exists in the list.
There are no data errors, nothing. It's just refusing to update the UI with the value I programmatically set.
Any help would be greatly appreciated as always.
Thanks
This code works for my first combo box I have in my row with the following code, but I try it with the next one in the row and it doesn't work. I could use the help with the rest I have 3 more to do. I do set the combo boxes on a second form from this form with the same code as is on the last line of the try block but using the cell information instead of the dataset
try
{
string strQuery = "select fundCode from vwDefaultItems where IncomeType = '" + stIncome + "'";
SqlDataAdapter daDefault = new SqlDataAdapter(strQuery, conn);
DataSet dsDefault = new DataSet();
daDefault.Fill(dsDefault);
strDefFund = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
dgvCheckEntry.Rows[curRow].Cells[7].Value = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
}
catch (Exception eq)
{
}

select * from here where THIS IS CHECKED

i am looking for a way to show data that are Checked(1) in my Database to a DataGrid, excluding those UnChecked(0)..
Sample Database:
Fruits?
Apple - 1
Mouse - 0
Grapes - 1
Pencil - 0
Orange - 1
Button_Click
... on DataGrid display only checked Data / Rows
this will help you to add checkbox column in grid then make code for checked & unchecked as per your database. same way you can fetch the data on the WHERE condition of the checked row cell value...
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "X";
checkColumn.HeaderText = "X";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10;
//if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values
dataGridView1.Columns.Add(checkColumn);

Resources