2 or more Controls only 1 is considered Active - c#

I have 2 controls (MyCtrl) next to each other called ctrlLeft and ctrlRight.
Whenever one receives interaction it is considered active (by default the left one). I override OnDraw and customize the look of the active one a bit.
Currently I have a property Active and an event that I subscribe to from all MyCtrl in there I store a reference to the active one like this:
if (sender is MyCtrl)
{
ctrlActive = (sender as MyCtrl);
ctrlLeft.Active = !(ctrlRight.Active = (ctrlActive == ctrlRight));
}
Either way I need to have ctrlActive as I use it for other things but what I am wondering is if this is the best way make them aware of each other?
Another option I thought of was to store references to every possible MyCtrl and then loop through em all and activate / deactivate the one that match sender just in case I in the future add a ctrlMiddle.
Are my thoughts wrong, is there better options to do this. For example, how does radiobuttons accomplish their similar functionality?
Edit: Thanks for all suggestions.
In my particular case I don't want/need a container as even if I have 3 MyCtrl only one can still be active and I don't want them to be "linked" 2 and 2 so I went with a public static MyCtrl { get; set; } that each control can check itself against and I can update it where I need to, which works in my case and rids me of the need to loop through a collection when using multiple MyCtrl.

Your methods are sound. If you need multiple controls with only one being active consider a container (visual or otherwise) where the children supply an "activate" event TO the container and the children also subscribe to a "control activated" event FROM the container....if the child is not the control supplied by the containers "control activated" event..then paint it as not active otherwise paint as active.

You have to manage the activation by yourself, so I think that your method is good.

I nearly had the same idea as Rusty. But i would make it a little more general.
Why not building a container control that contains two panels (like SplitContainer). The container control has a property Active of type enum ActivePanel { First, Second } and it can be switched from outside by a setter or automatically through a subscription of the container to the Focus event (or something similar).
With such an approach you also don't need a ctrlMiddle cause you can nest your container multiple times.
I think there are still some problems to solve by this idea, but it should give you a good direction.

Related

Recommended way to manipulate User Control panels into a Windows From

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.

Keep Control always on top

Is it possible to keep a control (Panel) always over all other controls even if they also use Control.BringToFront()?
I tired to use BringToFront itself, but it seems that this loose its effectiveness if another control under this control also uses this command.
It would help if you try to explain what are you trying to achieve. We might be then able to better convince you, that you are doing something very wrong :)
Anyway, no matter what trick you do, the other control may use the same trick to override you.
You can get step ahead for example by handling parent control's Layout event to force your control back to front. The Layout event is trigerred (among other) when child controls' Z-order is changed.
private void Form1_Layout(object sender, LayoutEventArgs e)
{
panel1.BringToFront();
}
A dirty way of dealing with this is setting a timer and everytime it ticks use the .BringToFront() method on the control, you can also add multiple controls you wish to perform this on and can arrange them however you like.

How can I create dynamic controls in response to a button click?

I want to fill an updatepanel with new dynamic controls in response to a button click.
However, I also want to be able to access the values of these dynamic controls in response to an event in one of the controls.
Specifically, I want the button to bring up two dropdownmenus. One of the menus (or both if need be) is in another update panel. I want the first menu in the update panel to change its data in response to a value getting selected in the other menu.
I think my problem is that when I cause a postback with one dropdownmenu I lose the other dropdownmenu because I created it in the button_click handler.
I know I should create dynamic controls in the Page_Init method (or so ive heard) but I only want the controls to show up if the button is clicked. There are other buttons on the page which need to create a different set of dynamic controls.
Thanks.
There are a lot of ways you can handle this, and which approach to take really depends on your project's requirements and your available resources.
The smoothest way to do it that would generally provide the best user experience would be to use a Javascript technique to hide and show controls as the page required them. JQuery is the library I would recommend for this. On the most basic level, you simply wire the control's activation (such as a button_click event) and hide or show a div containing the dynamic content as necessary, like so:
$("#control").show();
// and
$("#control").hide();
Alternatively, you can do this in C# by using the Visible property on many of the normal web controls for ASP.NET. The usual code-behind approach would look something like this:
private void btnControl_Click(object sender, EventArgs e)
{
var dynamicControl1 = FindControl("dynamicControl1");
dynamicControl.Visible = false; // or true, as the case may be
}
This particular approach is mostly attached to code-behinds, though, which I would encourage you to avoid if possible. They are practically impossible to test and will make projects a pain to work in. You can use a similar approach in the MVC3 framework, of course, it will just be a little different how you send and receive the control you are setting to not be visible. The other benefit this has that is kind of nice is that if something is set to not be visible, it tends not to even be displayed in the HTML generated by the templating engine (YMMV depending on the engine, but I know this is true in Razor). So someone viewing the source of your webpage won't be able to see inactive controls, which may or may not be something that appeals to you.
EDIT: I see the problem is less to do with how to display these things, and more with how to create and read them back given on-the-fly input.
I'm sure there's a way to do this with Javascript (which would more than probably be the cleanest and best way to do this), but I'm not good enough with JS to know the answer to that one. The way you would handle this in ASP.NET is make the div you're going to add controls to server-side (by using runat='server', then add what you need there. Again, the trivial code-behind approach would be something like:
private void btnControl_Click(object sender, EventArgs e)
{
foreach(var checkBoxChecked in chkBoxes.Where(x => x.Checked))
{
div.Controls.Add(new WebControl()) // or whatever the heck else it is you need.
}
}
This presumes that you have an IEnumerable<CheckBox> to iterate over, of course. You may also want an IList<WebControl> to keep track of all the junk you're adding. You will also need to make sure the CSS is applied properly to the div for the controls you're adding. And again, code-behinds are pretty awful and I use the example only because it'd be easy to spin up in a project to test for yourself.

C#: How to access public member of a custom control from another custom control

I am working on windows application form. I have a CustomControl (say MasterControl) on which i put a split panel and now my MasterControl is split into three parts say:
Pannel1
Pannel2
Pannel3
Now i develop three custom controls and put one in each of pannels e.g
Pannel1 have CustomControl1
Pannel2 have CustomControl2
Pannel3 have CustomControl3
Now somewhere in CustomControl3 I need to access a public member of CustomControl1. For which i wrote the following code:
((MasterControl)this.Parent)._oCustomControl1.PublicMember = this.PublicMember;
The code above doen't work in my case. When this line of code is executed in debug mode then a message box appears and states that "There is no code available for current location"
It's a really bad design for your controls to depend on how are the arranged on the parent container.
e.g. inside your third control, you are quering the property of the first one by accessing it from the parent, and then it's child control by name.
Your code will break very easily, if it can be compiled at all - I think the problem you're having is the order of compilation: in order for your parent form to be compiled, it needs to have child user controls finished. On the other hand the user controls you created need to have finished form.
It would be far better to set whatever behaviour you're after from the container of those controls - for example, by reacting to events from the control, and setting appropriate stuff on appropriate other controls (there are other ways as well ofcourse - the point is in the direction and flow of information - who's setting and using what).
If you have a split panel in your master control, you should go two levels up to find your master control:
((MasterControl)this.Parent.Parent)._oCustomControl1.PublicMember = this.PublicMember;
I found the answer by myself. I am positing here because it might help some one else.
The exact code is:
((MasterControl)this.Parent.Parent.Parent)._oCustomControl1.PublicMember = this.PublicMember;
Basically my coustomcontrol3 lies inside a split container panel, so when i wrote:
this.Parent then it points to Panel In which it is residing and if i wrote
this.Parent.Parent then it points to the spliter container in which above panel reside and if i wrote
this.Parent.Parent.Parent then it points to control in which this split container resides
I got the idea from "Farzin Zaker" answer, so thanks to him for his contribution

What is the best way to handle mutliple view/tab-ish GUI elements

I'm working on an application that presents the user with varied data, depending on the object being viewed. The objects are all of the same interface just with extended properties beyond once distinguished.
I'm looking for the "best" way to display a type-dependent control to the user. I would like to use tabs but I'm stuck with .NET 2.0 and from what I can gather the only way to hide/show tabs are to remove them and re-add them. That might be the best way but that leads to issues regarding blinking of the GUI components, keeping tabs on the active tab when reloading, etc.
I could make custom controls for each and either have them all loaded and hide/show when necessary (which I have done in the past on projects), or dispose and re-instantiate them...
To clarify best, I would say the closest balance between code elegance and program efficiency.
I have used and have had the best luck with loading them all and then showing/hiding the ones needed.
Disposing and re-instantiating everything always made things very messy.
In order to not have load time be horrible, you can instantiate them on first use. Something like:
IView LoadView(Type dependantType)
{
// get the view or create one
IView view = GetView(dependantType);
if (view == null)
{
view = InstantiateViewAndAddToForm(dependantType);
AddView(view);
}
//
// do some binding to your model or whatever here
//
// make the correct view visible
foreach (IView v in Views)
view.Visible = v == view;
}
Could you just create a panel for each object and have a dictionary associate the object type and the panel?
You could just tell the panel to bring to front if they are all the same size, or set all Panels.Visible to be false, and just set the one you need to be true.
I have used DockPanel Suite for applications that require multiple tabs.
It is an open source project, so you can actually modify the code if you wish.
The Suite has many functions, however, if you can just use the Tabs.

Categories

Resources