Dynamically-Added Custom User Controls Not Visible - c#

I have a form in C# with a drop down box. When that drop down box gets changed, I want it to load a custom user control into a panel. I get no compile errors, no runtime errors, but I also get no visible user control. The idea here is that each user control understands the configuration for a different scenario. I want to encapsulate each scenario in its own control and the drop down box allows the user to select the scenario, which loads the control for the user to perform configuration. By adjusting the options in the drop down, I can customize what scenarios a given customer has. As I said, my problem is I cannot get any of the controls to become visible. This is the code I am using for the drop down index change event handler:
private void ddlCollectorType_SelectedIndexChanged (object sender, EventArgs e)
{
m_currentControl = null;
pnlDeviceConfig.Controls.Clear ();
switch ((string) ddlCollectorType.SelectedItem)
{
case "SEL-421":
SEL421ASCIIControl s421 = new SEL421ASCIIControl (this);
m_currentControl = s421;
pnlDeviceConfig.Controls.Add (s421);
break;
case "SEL-421 (FTP)":
break;
case "GE D60":
GED6061850Control geD60 = new GED6061850Control (this);
m_currentControl = geD60;
pnlDeviceConfig.Controls.Add (geD60);
break;
case "GE D60 (TFTP)":
break;
case "MiCOM P442":
break;
}
}
I've only created a couple of the user controls so far, hence the empty case statements. When I make selections that should show me something, I get nothing (confirmed in the debugger that I am hitting the case statement body). Any help will be greatly appreciated!

To follow up on my comment, I'm guessing that the position and/or dimensions of your control are not set.
Try something like:
...
SEL421ASCIIControl s421 = new SEL421ASCIIControl (this);
m_currentControl = s421;
pnlDeviceConfig.Controls.Add (s421);
// TODO: Set real size and position.
s421.Left = 0;
s421.Top = 0;
s421.Width = 100;
s421.Height = 50;
break;
...
You also may use the Dock and Anchor properties of your control.

1 You can replace your Menu with PlaceHolder, he is ideal control for adding controls
here an example : http://www.developerfusion.com/code/3826/adding-controls-to-placeholders-dynamically/
2 And for your case you can try to adjust visible property of panel to true

Related

Is there a faster way of assigning an image to lots of buttons?

I have a Windows Forms Application that I need to assign an image to all 100 buttons, the problem is, that I need to do it randomly every time... Is there a faster way of doing this?
My first idea was to use the basic method of assigning that image to a variable and then assigning the image to the button:
Bitmap P_Farm = new Bitmap(#"IMAGE PATH.jpeg");
this.button1.Image = P_Farm;
But the problem with that is that I will need to do this for all 100 buttons.
this.button1.Image = P_Farm; // "P_Farm is just the path to the image"
this.button2.Image = P_Farm;
this.button3.Image = P_Farm;
this.button4.Image = P_Farm;
I want to keep my code as dry as possible.
The reason I can't just do it through the "Image" option in the "Properties" window is because eventually I will have a random image for every button on every load of the app. So first it will be
this.button1.Image = Z_Farm;
this.button2.Image = C_Farm;
this.button3.Image = P_Farm;
this.button4.Image = P_Farm;
then
this.button1.Image = P_Farm;
this.button2.Image = P_Farm;
this.button3.Image = Z_Farm;
this.button4.Image = Z_Farm;
I was wondering if it was possible to do something like reading every line in a text file but instead of the line changing with each try, the button changes
int i = 0;
while (true) // Something like this loop but changing not the line, but the button
{
this.button[i].image = P_Farm; // this obviously doesn't work
I++;
}
Hopefully this makes sense
Thanks a lot!
You can also loop through all the controls in your form, find the ones that are buttons and change their image that way. Of course you don't want to change them all. What I usually do is set a number to the Tag property:
foreach (Control control in Controls)
{
if (control is Button theButton && (int)theButton.Tag == 5)
{
theButton.Image = P_Farm;
}
}
This will not work if you have panels with buttons that you want to change too. You will have to write a recursive function that involves all the possible containers in your form such as panels.
If you want to change all the buttons in a container like a panel you would only change your foreach line to something like foreach (Control control in panel.Controls).
In the future, when you decide that not all buttons will have the same image, you could set an image based on the tag property like this:
foreach (Control control in Controls)
{
if (control is Button theButton && (int)theButton.Tag >= 5)
{
switch ((int) theButton.Tag)
{
case 100:
theButton.Image = P_Farm;
break;
case 101:
theButton.Image = Z_Farm;
break;
}
}
}
Because we are assuming that all buttons have an int in their tag property, you should add a number to all buttons, including those that should not change like your Cancel and Ok buttons. Something like a zero to exclude them from the image assignement.
I'm sure that there are better ways. I haven't done WinForms in a while.

Visual C#, how can I set SetItemChecked property using Control?

I have a form which contains several CheckedListBox items, along with other controls. I'm trying to loop through each the controls and set its property values. Unfortunately, the SetItemChecked property is is not available in the Control class, so I can't figure out how to manipulate the Checked state of the control.
Here's what I have so far:
for (int i = 0; i < Controls.Count(); i++) {
switch(Controls[i].GetType().ToString()) {
case "System.Windows.Forms.TextBox":
case "System.Windows.Forms.RichTextBox":
Controls[i].Text=i.ToString();
break;
case "System.Windows.Forms.CheckedListBox":
Controls[i].SetItemChecked(0,true);
// ^^ This line doesn't work, because SetItemChecked is not available
break;
default:
Controls[i].Tag=i;
break;
}
}
You can cast the Control into a CheckedListBox Like this:
(Controls[i] as CheckedListBox).SetItemChecked(0,true);
I'm not sure of this one, but it might work also:
CheckedListBox myCbList= (ChecekdListBox) Controls[i];
myCbList.SetItemChecked(0,true)

How to changes the items in a combobox based on the selected value of another combobox in C#

Once again I am in need of your assistance. I have two combobox's one called cmbRFR and one called cmbSubRFR. The items in the cmbRFR are:
Null
POSITIONING
ARTEFACT
PATIENT ID
EXPOSURE ERROR
TEST IMAGES
I need to set it up so that when the user selects one of the items in cmbRFR, it changes the items displayed in cmbSubRFR. cmbSubRFR should work as follows.
When user selects Null, the combobox should also display Null/a blank item.
When user selects POSITIONING:
Anatomy cut-off
Rotation
Obstructed view
Tube or grid centering
Motion
When user selects ARTEFACT the combobox should also display ARTEFACT.
When user select PATIENT ID:
Incorrect Patient
Incorrect Study/Side
User Defined Error
When user select EXPOSURE ERROR:
Under Exposure
Over Exposure
Exposure Malfunction
When user selects TEST IMAGES:
Quality Control
Service/Test
I have no code to provide for this one as I have no idea how to go about doing this. I have looked around at some other questions that are similar to this however I have found nothing that might help me.
Any suggestions would be helpful.
public partial class Form1 : Form
{
string cmbRFR_item;
public Form1()
{
InitializeComponent();
}
private void change_cmbSubRFR_items()
{
cmbSubRFR.Items.Clear();//Clear all items in cmbSubRFR comboBox.
switch (cmbRFR_item)//Adding your new items to cmbSubRFR.
{
case "Null":
cmbSubRFR.Items.Add("Null/a blank item");
cmbSubRFR.Text = "Null/a blank item";
break;
case "POSITIONING":
cmbSubRFR.Items.Add("Anatomy cut-off");
cmbSubRFR.Items.Add("Rotation");
cmbSubRFR.Items.Add("Obstructed view");
cmbSubRFR.Items.Add("Tube or grid centering");
cmbSubRFR.Items.Add("Motion");
cmbSubRFR.Text = "";
break;
case "ARTEFACT":
cmbSubRFR.Items.Add("ARTEFACT");
cmbSubRFR.Text = "ARTEFACT";
break;
case "PATIENT ID":
cmbSubRFR.Items.Add("Incorrect Patient");
cmbSubRFR.Items.Add("Incorrect Study/Side");
cmbSubRFR.Items.Add("User Defined Error");
cmbSubRFR.Text = "";
break;
case "EXPOSURE ERROR":
cmbSubRFR.Items.Add("Under Exposure");
cmbSubRFR.Items.Add("Over Exposure");
cmbSubRFR.Items.Add("Exposure Malfunction");
cmbSubRFR.Text = "";
break;
case "TEST IMAGES":
cmbSubRFR.Items.Add("Quality Control");
cmbSubRFR.Items.Add("Service/Test");
cmbSubRFR.Text = "";
break;
}
}
private void cmbRFR_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbRFR_item!= cmbRFR.SelectedItem.ToString())//This will control your changes in cmbRFR about selected item and call change_cmbSubRFR_items()
{
cmbRFR_item = cmbRFR.SelectedItem.ToString();
change_cmbSubRFR_items();
}
}
}
There are two ways to go about solving this. First the "correct way", which is to set the DataSource property. Create lists for each combobox, like this:
var _positioningItems = new List<string> { "Anatomy cut-off", "Rotation", "Obstructed view" };
var _patientIdItems = new List<string> { "Incorrect Patient", "Incorrect Study/Side", "User Defined Error" };
Then subscribe to the OnSelectedIndexChange event on the cmbRFR combobox and then in the event handler, set the DataSource to the appropriate list.
The other way to do it, which I'm not in favor of, is to create comboboxes for each cmbRFR item, then hide them all and only show the appropriate one to the user. Subscribe to the OnSelectedIndexChange event on the cmbRFR combobox and hide/show the appropriate combobox.

ObjectListView editing doesn't work

I'm trying to create a simple listbox with ObjectListView (WinForm, C#). The goal is to have a single value (a double) and a check box.
I want to be able to edit the double value by Single Click, so here are the relevant lines of code from my MyWindow.Designer.cs file (i've left out the default values for efficiency):
this.olvDepths = new BrightIdeasSoftware.ObjectListView();
this.olvColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
...
this.olvDepths.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick;
this.olvDepths.CheckBoxes = true;
this.olvDepths.CheckedAspectName = "IsDefault";
this.olvDepths.FullRowSelect = true;
//
// olvColumn1
//
this.olvColumn1.AspectName = "Depth";
this.olvColumn1.Text = "";
this.olvColumn1.IsEditable = true;
I then create a list of my class (ShieldingEntry) and use the olvDepths.SetObjects() with the list. My ShieldingEntry class looks like this:
public class ShieldingEntry
{
public double Depth { get; set; }
public bool IsDefault { get; set; }
}
However, when I click the field, it doesn't go into edit mode. I've also tried the DoubleClick, SingleClickAlways, and F2Only modes and they don't work either.
The Checkbox works fine.
************** I have additional information *********************
I've pulled and build the ObjectListView source, so I could step through it.
I put a breakpoint in the OLV StartCellEdit method and it gets called and appears to setup and select the control appropriately. It just never appears...
As I noted in the comments on the answer below, I've got this control on a tabbed dialog, and if I switch to another tab, then back, the control works fine.
What am I missing?
I've used ObjectListView before, and here is what I had to do:
Handle the CellEditStarting event. This event is raised when the cell goes into edit mode. Since OLV doesn't really have built-in editors, you have to make your own. Then handle the CellEditFinishing event to validate the data before putting it back into your model.
So first, handling the CellEditStarting event:
private void objlv_CellEditStarting(object sender, CellEditEventArgs e)
{
//e.Column.AspectName gives the model column name of the editing column
if (e.Column.AspectName == "DoubleValue")
{
NumericUpDown nud = new NumericUpDown();
nud.MinValue = 0.0;
nud.MaxValue = 1000.0;
nud.Value = (double)e.Value;
e.Control = nud;
}
}
This creates your editing control. If you want to make sure the size is right, you can set the size of the control (in this case a NumericUpDown) to the cell bounds using e.CellBounds from the event object.
This will show the editor when you click in the cell. Then you can handle the editor finished event to validate the data:
private void objlv_CellEditFinishing(object sender, CellEditEventArgs e)
{
if (e.Column.AspectName == "DoubleValue")
{
//Here you can verify data, if the data is wrong, call
if ((double)e.NewValue > 10000.0)
e.Cancel = true;
}
}
I don't think handling it is required, but its good practice to validate data from the user.
The editing control in the CellEditStarting event can be any control, even a user defined one. I've used a lot of user defined controls (like textboxes with browse buttons) in the cell editor.
[Edit]
I uploaded an example here dropbox link that seems to work. Might not be in the exact view as needed, but seems to do the job.
For anyone else with this problem. I had it specifically when trying to edit a 'null' value in a decimal? on the OLV on a tab page. Solution for me was to set UseCustomSelectionColors to 'False'. I didn't look elsewhere to see if it was reported as a bug. Seems like a bug.

TreeList devexpress icons

I use Difference class as my datasource in treelist. Then I would like to show different icon with node according to property value of the type Difference. Here is my Code:
treeList1_GetStateImage(object sender, DevExpress.XtraTreeList.GetStateImageEventArgs e)
{
TreeListColumn tlColumn = treeList1.Columns["DifferenceType"];
DifferenceTypeEnum differenceType = (DifferenceTypeEnum)e.Node.GetValue(tlColumn);
switch (differenceType)
{
case DifferenceTypeEnum.Added:
e.NodeImageIndex = 0;
break;
case DifferenceTypeEnum.Deleted:
e.NodeImageIndex = 1;
break;
case DifferenceTypeEnum.Modified:
e.NodeImageIndex = 2;
break;
default:
throw new Exception("Difference with not specified type");
}
I would like to have the same icons when selected and when not selected and thats all, nothiung else, but now each time I click on a node NodeImageIndex is changed to 0, WHen nodes arent selected everything work fine,
ehh Im tired of this ...
thanks for any help
I would suggest that you also handle the GetSelectImage event to define which image should be shown when a certain node is selected.
I just want to know how can I connect specified icon with node according to the property of the type. Lests say Im bound to the fruit list andd if fruit has gaot typoe property set to banana let the image be banana.png if apple then apple.png and so on :)
imageCollection connectied with this treelist has got these images with corresponding indexes.

Categories

Resources