C# WinForm TabControl Formatting Issue - c#

When programmatically adding controls to a tab control, I have been using the Form_Load event to create and embed things like datagridviews into my UI. I made a class that inherits from DataGridView
class DBDataGridView : DataGridView
{
public DBDataGridView()
{
DoubleBuffered = true;
AllowUserToAddRows = false;
AllowUserToDeleteRows = false;
AllowUserToResizeRows = false;
AllowUserToOrderColumns = false;
AllowUserToResizeColumns = false;
RowHeadersVisible = false;
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
ReadOnly = true;
Dock = DockStyle.Fill;
SelectionMode = DataGridViewSelectionMode.FullRowSelect;
TabStop = false;
}
}
And I call it later in the Form_Load event like so
private void MainDesignerForm_Load(object sender, EventArgs e)
{
DBDataGridView _DGV = new DBDataGridView();
var listOfOverlays = new List<OverlaySelectionList>()
{
new OverlaySelectionList { Description = "Description 1", PartNumber = "123-R1"},
new OverlaySelectionList { Description = "Description 2", PartNumber = "456-R1"}
};
var overlayList = new BindingList<OverlaySelectionList>(listOfOverlays);
_DGV.DataSource = overlayList;
Tab_Overlay.Controls.Add(_DGV);
_DGV.ClearSelection();
}
This gridview is on the THIRD tab of the TabControl, and everything works as expected except the ClearSelection(). No matter where I call it, it does not clear the initial row selection of the DGV. However, if I fire the same code block from a button ON the third tab, the formatting AND the ClearSelection() behave as expected.
What is causing this behavior?

Thanks to 41686d6564 and Jimi for the insight into the specifics on why this was happening.
Reiterating what they said in the comments: Assignment of properties appear to be cached regardless of whether the control they belong to is active or not (Hence why all the sizing and formatting properties were present at run time). However, actions that require a handle, like ClearSelection() require the control to be shown and active for the intended behavior to be observed.
Setting the selected tab to where the DataGridView before calling ClearSelection() was the solution (Or in my case, I had nested tabs, so I had to follow the tab tree to get to the specific tab that the DataGridView was on)
So now, part of the Load_Form logic is to check WHERE the control is located, make that tab active, THEN format and clear selections for each control that is being added. This allowed ClearSelection() to work as intended.

Related

ToolStripMenuItem strange behavior on visible property [duplicate]

This question already has an answer here:
How to set a ToolStripMenuItem Visible in code?
(1 answer)
Closed 1 year ago.
I have encounter that issue a long time ago and again now. I cannot figure out what special thing had to be done to edit the ToolStripMenuItem control a Visible property while inside a form load.
in designer.cs
private System.Windows.Forms.ToolStripMenuItem mnuExport;
//
// mnuExport
//
this.mnuExport.Name = "mnuExport";
this.mnuExport.Size = new System.Drawing.Size(116, 22);
this.mnuExport.Text = "Export";
this.mnuExport.Visible = false;
this.mnuExport.Click += new System.EventHandler(this.mnuExport_Click);
in the form code
public partial class MainBuilder : Form
{
private void MainBuilder_Load(object sender, EventArgs e)
{
mnuExport.Visible = true;
}
}
In the code above export is a menu item of type ToolStripMenuItem which trough the property grid in the form design mode I have modified it's Visible property to false. So in the form load I want to switch to the visible state to true. I thought it be easy so I coded all the logic around and it failed. So I decided to remove all my code and simply hardcode the set to true and to my surprise this does not work.
When I put the breakpoint on the line in the form_load I clearly see it's false and if it let the line run the value is still false.
I recall seeing this issue in the past but cannot find anything about it. I also tried with 4-5 other menu item in that window and they all show the same behavior.
EDIT
just tried to put visible = true in the designer.cs instead and in the form_load still tells me the value is false. There is some major issues here.
As mentioned in the comments the property Visible getter does not reflect the actual inner property value until later in the lifecycle. It is still unavailable in the form_loaded event. My main problem is that one menu visibility state was based on if all sub menus are not visible then it should not either. To do so I was iterating on it's child and checking the Visible property. The problem is them having Visible to false due to the way it works the parent set it's own Visible to false as well.
I don't like the solution but that's the only way to make it work
// get all sub menus
var subMenus = mnuExport.DropDownItems.Cast<ToolStripItem>().ToList();
// create a list of bool that will store the visible state I want the controls to have. put them to true by default
var menusVisibleStates = Enumerable.Repeat(true, menus.Count).ToList();
// set the visibility state of each sub menus
for (int i = 0; i < menus.Count; i++)
{
// some logic is here that choose true or false but is irrelevant here
var visibleStateIWant = true;
// set the visible state stored
menusVisibleStates[i] = false;
// set the actual control value that will change later on
menus[i].Visible = false;
}
/// now here I use the state I have specified and NOT the menu object property
mnuExport.Visible = menusVisibleStates.Any(o => o);

Getting list of checked radiobuttons in .net

TLDR; Looking for a method to retrieve all radiobuttons by means of something like this... (psudo)
List<RadioButton> btn = new List<RadioButton>;
btn = stackPanel.getAllRadioButtons()
I am currently building a little quiz application in C#. I have functions that add the required GUI elements to a groupbox. I would like to know if there is any way that I can loop through the created elements (for instance radio buttons) to see which are checked.
Here is one of the functions along with how they are added to the window.
private void tfQ(string questionBody)
{
StackPanel questionPanel = new StackPanel{Orientation = Orientation.Vertical};
questionPanel.Children.Add(new Label { Content = questionBody });
GroupBox group = new GroupBox();
RadioButton trueRadio = new RadioButton();
trueRadio.Content = "True";
RadioButton falseRadio = new RadioButton();
falseRadio.Content = "False";
questionPanel.Children.Add(trueRadio);
questionPanel.Children.Add(falseRadio);
group.Content = questionPanel;
mainStack.Children.Add(group);
}
Constructor:
public quiz()
{
tfQ("This is a true/false question");
Window w = new Window();
w.Content = mainStack;
w.Show();
}
I have found many ways to do it in the C# scripting format
(using the Control function ...)
var checkedButton = container.Controls.OfType<RadioButton>()
.FirstOrDefault(r => r.Checked);
but I have not yet found a "programmatic" way of doing it. I have considered changing the type of void tfQ to a StackPanel, but that only helps me to easier loop through the stack panels, althought that only partly solves me problem - allows me to easier loop through the StackPanels but I still don't know how to get the RadioButtons on a panel.
P.S I am very new to C# - with experience in Java/C/C++/Python
I made use of the following code to cast the content into a new groupbox and stackpanel, respectively.
if (child is GroupBox)
{
if ((child as GroupBox).Content is StackPanel)
{
StackPanel d = (StackPanel)((GroupBox)child).Content;
}
}
This allowed me to cast the content into a local copy of a control. It may not be the best way - I'm sure it is very inefficient to be honest. Solved the problem.

choosing to hide or show tooltips based on bool

so I figured I'm making just a stupid mistake here. In the first of what will be many controls, I need to either show a balloon tooltip when a bool is true or not show them when the bool is false. I know that ShowAlways is not what I need to modify and I've tried various solutions already. Does anyone spot the problem? The bool is set by a checked dropdown item in a Help Menu Strip Item.
It will open with the application with the correct display, but as soon as I check that option to show it, it always shows there after.
public void changeBalloonProperties(bool boolSet)
{
ToolTip helpDeskInfoButtonToolTip = new ToolTip();
if (boolSet)
{
helpDeskInfoButtonToolTip.ToolTipTitle = "HelpDesk Information Button";
helpDeskInfoButtonToolTip.UseFading = true;
helpDeskInfoButtonToolTip.UseAnimation = true;
helpDeskInfoButtonToolTip.IsBalloon = true;
helpDeskInfoButtonToolTip.ShowAlways = true;
helpDeskInfoButtonToolTip.AutoPopDelay = 5000;
helpDeskInfoButtonToolTip.InitialDelay = 1000;
helpDeskInfoButtonToolTip.ReshowDelay = 500;
helpDeskInfoButtonToolTip.SetToolTip(helpDeskButton, "Click to launch HelpDesk user info page in default browser.");
}
else
{
helpDeskInfoButtonToolTip.RemoveAll();
}
}
You are creating a new ToolTip instance each time the changeBalloonProperties is called so the code isn't removing the caption associated with the original ToolTip that was used with the helpDeskButton. Try moving the ToolTip declaration outside of your changeBalloonProperties method so the same ToolTip object is used with RemoveAll().
Also note you can use that same ToolTip object to add captions for multiple controls (as shown in the sample here) and it's probably better to set helpDeskInfoButtonToolTip.Active = false to disable them all at once instead of setting and removing the captions (and other properties) each time you toggle.

How to add tooltip to user defined textbox on a winform

I have a uvSelfLoadingTextBox with multiple instances on a form.
I would like to load the tooltip with the _value property at run time.
I've tried
public ucSelfLoadingTextBox()
{
Windows.Forms.ToolTip myToolTip;
myToolTip.AutomaticDelay = 5000;
myToolTip.AutoPopDelay = 50000;
myToolTip.InitialDelay = 100;
myToolTip.ReshowDelay = 500;
myToolTip.SetToolTip(this, _value);
inside the control but that does not work.
I have tried using the tooltip that is dragged onto the form
ucSelfLoadingLogicTextBox uc = new ucSelfLoadingLogicTextBox();
toolTipA.SetToolTip(uc,uc._value );
and that does not work.
What is the correct way to do this?
You forgot to instantiate myToolTip. You need to set it to new Tooltip().
Also, I don't think it's a good practice to assign the tooltip in the textbox's constructor. You could do this in OnCreateControl() (that you need to override).
Your code could therefore become:
protected override void OnCreateControl()
{
base.OnCreateControl();
var myToolTip = new System.Windows.Forms.ToolTip
{
AutomaticDelay = 5000,
AutoPopDelay = 50000,
InitialDelay = 100,
ReshowDelay = 500
};
myToolTip.SetToolTip(this, this.Text);
}
Many visible controls on windows form have ToolTip property. Just set the Tooltip with your newly created one. You can also add tooltip to your form. Have you tried this?
myToolTip.ShowAlways = true;
And try to set this tip to a button control. This may be a good test for your tooltip.

Events not firing for dynamic columns in SharePoint DataGrid

In a Web Part for Sharepoint, I'm trying to add a variable number/ordering of ButtonColumns to a DataGrid dynamically based on an option the user has selected. The problem is that the dynamic columns aren't firing off the events I set up on the DataGrid (such as SelectedIndexChanged). When the table originally constained a static set of columns, they were created in CreateChildControls() and everything worked peachy. However, since they are now dynamic, I have to delay adding them until after a search button's click event fires. I was wondering if there was some place I needed to move the column creation to that still allowed it to be dynamic but also allowed it to register/fire events.
outputDG creation in CreateChildControls():
outputDG = new System.Web.UI.WebControls.DataGrid();
outputDG.CellPadding = 4;
outputDG.HeaderStyle.Font.Bold = false;
outputDG.HeaderStyle.Font.Name = "Verdana";
outputDG.HeaderStyle.BackColor = Color.FromArgb(242,242,242);
outputDG.HeaderStyle.ForeColor = Color.FromArgb(128,128,128);
outputDG.HeaderStyle.Wrap = false;
//outputDG.ItemStyle.BorderColor = Color.Navy;
outputDG.HorizontalAlign = HorizontalAlign.Left;
//outputDG.BorderWidth = 1;
outputDG.GridLines = GridLines.Horizontal;
outputDG.Width = propsMgr.SearchGridWidth;
outputDG.PageSize = 10;
outputDG.AllowPaging = true;
outputDG.PagerStyle.Mode = PagerMode.NumericPages;
outputDG.PagerStyle.PageButtonCount = 5;
outputDG.PagerStyle.NextPageText = "Next Page";
outputDG.PagerStyle.PrevPageText = "Previous Page";
outputDG.PagerStyle.Visible = true;
outputDG.PageIndexChanged += new DataGridPageChangedEventHandler(this.outputDG_PageIndexChanged);
outputDG.AllowSorting = false;
outputDG.SortCommand += new DataGridSortCommandEventHandler(this.outputDG_SortCommand);
outputDG.SelectedItemStyle.BackColor = Color.FromArgb(255,244,206);
outputDG.SelectedIndexChanged += new EventHandler(this.outputDG_SelectedIndexChanged);
outputDG.ItemCreated += new DataGridItemEventHandler(this.outputDG_ItemCreated);
outputDG.AutoGenerateColumns = false;
outputDG.ItemCommand += new DataGridCommandEventHandler(outputDG_ItemCommand);
Controls.Add(outputDG);
During the search button's click event:
ButtonColumn buttonColumnSelect = new ButtonColumn();
buttonColumnSelect.ButtonType = ButtonColumnType.LinkButton;
buttonColumnSelect.CommandName = "Select";
buttonColumnSelect.HeaderText = "Column";
buttonColumnSelect.DataTextField = "columnField";
outputDG.Columns.Add(buttonColumnSelect);
And then later on it that same event I go through the result set and add in my data rows. Like I mentioned, this all worked back when the ButtomColumn code was up in CreateChildControls(), but it stopped working as soon as it was moved into an event. My best guess is that the event for the column doesn't have a chance to register in order to fire since it's happening from a different event. If I need to tackle this problem by building up the DataGrid differently, I'm definitely willing; I just need to be able to dynamically specify different columns to use.
maybe u need to set the ID-Attribute on the DataGrid.
otherwise it would be difficult for asp to find your control.
The fix for my case was to move the adding of the columns to the page's load event and the adding of the DataGrid to the controls after all of the columns are added.

Categories