I am assigning a custom class with some information I need for each TabPage created:
MyClass custom = new MyClass();
TabPage tabPage = new TabPage();
tabPage.Text = ...;
tabPage.Tag = custom;
tabPage.Controls.Add(...);
Unfortunately, the moment I click between tabs, or have a context menu and click something, the Tag object is lost.
From my understanding, you can set and use whatever you want inside Tag objects, so what's the issue?
I need this to be persistent until I want it to.
The issue still persists without explanation. I even tried this post, with the same result.
Apparently, I was using a third party library that has setting "HotTrack" information as boolean (true/false) using the Tag property of the TabPages.
Removing this in the library (as I do not need it) allowed me to store my own information without getting lost or overriden.
Related
I just started working with Visual Studio C# and to be honest I didn't fully understand what happens when we chose to hide a form or a user control.
My intuition tells me this hide/show method is kind of "inefficient" way to get an user through all the functions of my app.
So I am asking you guys if there is another workaround to "load" user control parts in a form.
Right now my main_menu form has all the user control objects placed on the form, but hidden, and I am using buttons to show them.
Is there a better way to achieve the same result? (I was thinking of a workaround like having an empty panel where I can load the User Control - not sure if possible)
Thank you!
You can create the controls on the fly and add them to or remove them from the Controls collection. On the class level, define this field
private Control _currentPanel;
You can use a more specific type here, if you are deriving all your panels from a common base type.
Then change the panel with
// Remove previous one.
if (_currentPanel != null) {
Controls.Remove(_currentPanel);
}
// Add new one
_currentPanel = new MyNewPanel();
//TODO: possibly set the panels Docking property to Fill here.
Controls.Add(_currentPanel);
In the example I am working with the form's Controls collection; however, you might have to use the Controls collection of some container control holding the panel.
I want to create a custom MessageDialog which in terms of its interface is exactly the same as the provided MessageDialog except for one thing; The Content property acts like that of a ContentControl so I can place custom UI elements in it.
Though I cannot for the life of me figure out how the developers were able to create a class that could be 'shown' in the UI without specifying that it inherits from any sort of control in the framework.
How is it possible to create a regular class and specify its 'Template' in code?
Thank you
You can accomplish this by creating a Popup, set it's Child. and then open it. You can create any XAML controls in code, so this is not an issue.
Popup popup = new Popup { Child = CreateXamlControlInCode() };
popup.IsOpen = true;
For step by step instructions, see this blog post.
There are two forms in my project and I am trying to add the controls of Form2's panel into Form1's panel.
So,
Form2 form2 = new Form2();
new_panel = form2.Controls["panel1"] as Panel; // form2's panel
this.panel.Controls.Add(new_panel); // add form2's panel into form1's panel.
And suddenly, the form2.Controls["panel1"] becomes NULL.
I can't understand why it happens.
A control can only have one parent - if you add a control which already has a parent to another control, it will remove itself first.
From the docs for ControlCollection.Add:
A Control can only be assigned to one Control.ControlCollection at a time. If the Control is already a child of another control it is removed from that control before it is added to another control.
If you think about it, that makes sense - a panel needs to know where it is, how big it is etc. It can really logically only be in one place at a time.
As an aside, I'd recommend using a cast rather than as when you're proceeding unconditionally as if the cast has worked - that way, if the relevant object isn't of the right type, you get an exception at the earliest moment of detection, instead of a null reference propagating itself through your system, possibly not being picked up for a long time (making it harder to diagnose the issue and introducing the possibility of data being lost).
I need to create a user control in C#.Net, which can be added to the application without being visible - just like the FolderBrowserDialog. It's a new window which I'll be using often so I think this is the right way. The window will be opened by envoking the showDialog-Method as known from the other dialog.
Any Idea?
Thanks and regards,
Daniel
Since all these "invisible" controls derive from Component class, you should start by reading the MSDN article on it: http://msdn.microsoft.com/en-us/library/system.componentmodel.component.aspx.
simply set Visible to false or isn't this what you're asking for ?
A UserControl is by definition not a Form; I think what you really want is a Component. That said, couldn't you really just create a new Form class that has the functionality you want? Whenever you want to display it, create a new instance and call ShowDialog. Or, if you want to preserve state, add an instance as a class member to your parent form, call its Show method whenever you want to display it, and add an event handler to its FormClosing event to check:
if (e.CloseReason == CloseReason.UserClosing)
and, if so,
e.Cancel = true;
Hide();
(This last part is to prevent errors if the user closes the form and then tries to display again after it's been disposed.)
I think more information may be needed, but if your crating a custom user control, the control should have a .Visible property. The follow is an example of how a button can be located on the form but hidden from a user.
button.Visible = true; // shows the button
button.Show(); // Shows the button
button.Visible = false; // hides the button
button.Hide(); // Hides the button
While the button may still be on the form/control, it will not be interactible by the user. You can still perform programmatic control on the button, but essentially it is not a user control while it is 'hidden'. If you want there to be a sort of hidden button that the user can click you will need to do other things to obtain this but It doesn't should like that is what you want.
This show/hide thought process sounds a lot like pains and confusion leftover from classic VB. The old form methods of show and hide, etc., were confusing and often left me as a developer in a position to not know whether an object existed or if was merely invisible. And checking was only trivial if you used On Error Goto to prevent a null reference. So right off I would advise not to think in terms of visibility unless you are doing something with a web page and need to maintain space and state.
First, create a Windows form and add it to your project, assuming that is the type of project that you are describing. Decorate the form with the proper controls, and where applicable, create properties to allow public access to the control values. Also set the DialogResult property of the buttons that either "OK" or "Cancel" the form. Give it an appropriate border style of either Fixed3D or FixedDialog. Maybe also set the property for where you want the form to appear on startup -- center parent, center screen, Windows default, etc. The event handlers for both "OK" and "Cancel" should invoke this.Close(); to close the window.
From the calling point in the code, here's some hypothetical code to get you going in the right direction. Write something like this in the place where you want to invoke your Dialog.
int intResult = 0;
string strResult = null;
MyDialogForm frm = new MyDialogForm();
frm.Title = "Select an Item";
frm.SomeProperty = 0;
frm.SomeOtherProperty = true;
if (frm.ShowDialog() == DialogResult.OK)
{
intResult = frm.Result;
strResult = frm.StringResult;
}
else if (frm.ShowDialog() == DialogResult.Cancel)
{
// User clicked the cancel button. Nothing to do except maybe display a message.
MessageBox.Show("Canceled Task");
}
...
// Somewhere further on down, but within scope, simply repeat
// what you just did, but without having to reinstantiate the
// form Window. But if you make it that far within the same
// scope, this method might be too busy and may need to be
// factored down.
So in short:
Scrap show/hide -- its not a good
practice.
Save the form data without
using an invisible form to save it;
that's the class's job.
If the UI requires a lot of flipping back and
forth between windows, check your
design for other alternatives for
solving the original problem. Maybe a design pattern such as MVC is for you, depending upon the size and complexity of your application.
Sound good?
You can put that control in a Panel. Set the panel height = 0 visible = false when you dont want to show the control.
And do the vice versa when you want to show it.
Derive from Control, not UserControl, and in the constructor set Visible = false.
Also create an event handler in the constructor.
VisibleChanged += new EventHandler(SetVisibleFalse);
Create a method named SetVisibleFalse.
private void SetVisibleFalse(object sender, EventArgs e)
{
if (Visible) Visible = false;
}
I have a simple user control with a text box and label in it. I created public properties to access the text in the textbox when I use the user control in another form.
My problem is the property is returning null value when I call it in the form. Am i missing anything?
My property is as follows::
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string rtnTxtMake
{
get
{
return txtMake.Text;
}
set
{
txtMake.Text = value;
}
}
}
and in the next forms button click event i call the property as follows
UserControl1 Usc = new UserControl1();
string Make = Usc.rtnTxtMake;
MessageBox.Show(Make)
UserControl1 Usc = new UserControl1();
string Make = Usc.rtnTxtMake;
If your user control has by default an empty textbox field, then it seems correct that the above two lines of code would return either null or String.Empty (check via String.IsNullOrEmpty), since you explicitly create a new instance of your user control.
I suppose what you really want is this:
You have inserted a user control into a form in the Designer. Let's call this user control instance ctlUser.
You have a button with a Click event handler. The last few lines of code in your question are from that handler method.
In the handler, you wouldn't create a new instance of your user control (Usc) but refer to the one that you previously inserted into your form, ctlUser. Then things should work as expected.
Your UserControl must be added to the Controls collection of a parent Form/Control before it can be properly initialized. Normally you would not write the code yourself that creates and adds the UserControl.
Instead, first build your project, then go to the Deisgner view of your main form and look at the Toolbox.
Your UserControl name (and an icon) should appear towards the top of the toolbox, and you can simply drag it to the main form. The Windows Forms designer will automatically generate the needed initialization code for you.
You should not create a new instance of your control in your button click event handler. Using the Designer approach to create your control you can simply access the existing instance of your control as follows:
public void button_Click(object sender, EventArgs e)
{
// myUserControl1 has already been created and initialized by the Deisgner generated code
// Note the name 'myUserControl1' is just an example, yours may be different.
string controlText=myUserControl1.rtnTxtMake;
// Or to change the UserControl textbox value
myUserControl1.rtnTxtMake="Testing";
}
What exactly to you mean when you say that the property is returning a null value? Is it actually null, or is your MessageBox simple showing empty?
I quickly duplicated your code and it behaves exactly as expected - the MessageBox shows, but it is empty because the default value of the Text property of the TextBox control is an empty string.
Also, the way you are approaching this is a little unusual.
Firstly, the line:
UserControl1 Usc = new UserControl1();
You do not generally need to instantiate a user control like this. Instead you can drag the control from the toolbox onto the design surface of your form. This will then take care of instantiating and initialising your control for you.
I think that this is actually your problem - when you include the line of code above, you are creating a new instance of the user control, and this is is no way realted to the user control that you have dragged onto the designer.
If you go to the designer view of your form and click on the user control, you should see a properties window somehere. If you do no, then either select it from the View menu, or press F4. In the list of properties, there should be one "Name" this is the programatic name generated for your user control. You can change this here if you want, but when you refer to this control in the rest of the form, this is what you must use.
Secondly, the next two lines:
string Make = Usc.rtnTxtMake;
MessageBox.Show(Make)
You can access the property rtnTxtMake directly. Unless you later need to access the Make string in the rest of your code, then directly accessing the property would usually be considered better style.
MessageBox.Show(userControl.rtnTxtMake);