|
The area of an MDI container window is covered by an MdiClient control; consequently, Form.BackColor and Form.BackgroundImage are ineffective. So How to set the background for this form.
|
|
|
|
|
I would think you need to do P/Invoke for that...
Philippe Mori
|
|
|
|
|
You could, but it's worthess and will slow down your applications rendering speed.
Again, you can't do it as design time. You have to do it at runtime.
Again, you have to enumerate through the MdiParent Controls collection. Once you find the MdiClient control, you can set its BackgroundImage property to whatever you want.
|
|
|
|
|
+5 Right on target, Dave, and you reminded me of when ... several years ago ... I did some stuff with MDI (yuck), and I went back today, and took a look at the MdiClient component that is created when you set a Form's IsMdiContainer Property = true.
The WinForms designers, probably having a bad hair day, set the Text and Name properties of MdiClient to an empty string, which means you can't do something like this to find it:
private MdiClient theMDIClientControl;
Control[] potentialMDIClientControls = this.Controls.Find("MdiClient", false);
if (potentialMDIClientControls.Length > 0) theMDIClientControl = potentialMDIClientControls[0] as MdiClient; So, as you said, you gotta iterate/enumerate over the Controls collection of the Form.
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
Very true. I found the lack of a name a little annoying at first, but I now prefer to find it by type. You really can't change the type at all, but the name can be changed breaking existing code.
|
|
|
|
|
If your question means you want a solution where there is one MDI container Form with a background image, and all the Forms on it ... interpreting "client" to meaning an 'mdi child form:' someForm.MdiParent = MDIContainerForm ... show a background as if they were 'transparent,' and you were seeing the portion of the MDIContainerForm's background their current bounding-box covers ...
You are in for some deep-plumbing, and as others comment here, it ain't worth it.
Now if the MDI container form just has a background that's a texture, then it's easy, but I'm pretty sure you are asking about the container form having a background picture, not a texture.
However, if you have the option of not using the MDI architecture, there are some ways you can 'simulate' the effect of contained Forms having the same background image. You make them transparent, and you "do the right thing" so that at run-time they remain in the boundary of the intended container control.
If you wish to hear about the specifics of this alternative, just ask.
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
You can set the background by casting the type to MDIClient and setting the MDIClient background. EXAMPLE:
private void Form1_Load(object sender, EventArgs e)
{
MdiClient ctlMDI;
foreach (Control ctl in this.Controls)
{
try
{
ctlMDI = (MdiClient)ctl;
ctlMDI.BackColor = Color.White;
}
catch (InvalidCastException exc)
{
}
}
}
|
|
|
|
|
Alisaunder wrote: try
{
ctlMDI = (MdiClient)ctl;
That is so ugly. I suggest you read up on the is and as keywords.
|
|
|
|
|
Not to mention using a try/catch to find the correct control is slow as exceptions are expensive objects to create.
Exceptions should be used to handle exceptional cases, not used in main logic.
A much better and faster implementation would have been to check the type of the control first, then cast it to an MdiClient if appropriate.
|
|
|
|
|
|
I don't care. Those examples are not there to demo best practices. Those examples are not considered "production-level" code.
|
|
|
|
|
I'm so glad your opinion isn't all that matters then.
|
|
|
|
|
I'm not the only one telling you the practice sucks...
|
|
|
|
|
And yet neither of you are displaying an alternative that is better?
|
|
|
|
|
I'm not in the spoon feeding business, I did provide the two keywords that exist for dealing elegantly with such situations. So if you want to learn something, look them up and read the reference material.
|
|
|
|
|
So sorry you don't feel like trying to answer the ops question with something less cryptic. Seems forums just aren't as helpful as they used to be. Since you feel you are such an expert that you you don't need to provide examples my opinion, for what it's worth is that you are no help at all and shouldn't even be posting.
|
|
|
|
|
Yeah, right. A couple of Code Project MVP's aren't very helpful at all. The pile of 5-voted responses to questions just doesn't offer up any evidence at all of us being helpful.
I'm not in the spoon-feed business either. There are just WAY too many very basic concept questions being asked that are very easily answered simply by typing the question into Google.
I'd rather have someone learn how to do research themselves than just keep asking question after question about very basic topics.
|
|
|
|
|
Actually Most everyone I know searches for the answers before hitting a forum with a question. Personally in my opinion it's more professional to offer assistance with a basic code example in the hopes the op learns something in the process. All anyone is learning from your responses is not to ask you for help.
|
|
|
|
|
Actually Most everyone I know searches for the answers before hitting a forum with a question.
I don't agree with you : if you see the questions these days it is obvious that more and more people consider this forum as a 'code self-service'. Plenty of questions wouldn't have been told if the OP took time to search for it on CP or on Google first.
No memory stick has been harmed during establishment of this signature.
|
|
|
|
|
Yeah, and most everyone I know Googles for answers before asking questions too.
But, yet, here we are, still looking at piles and piles of questions on very basic concepts.
The world doesn't follow in your footsteps either.
|
|
|
|
|
Apparently you haven't been reading the posts.
You also apparently won't be happy until you see actual code:
private void MdiClientExample()
{
foreach (Control c in this.Controls)
{
if (c is MdiClient)
{
MdiClient mc = (MdiClient)c;
...
}
}
}
Are you happy now?
Oh, and by the way, I don't consider this production quality code either. It's just cleaner than the example Microsoft gave.
And if you're going to critisize us, you might want to start by creating your own code samples instead of lifting and posting others as your own work.
|
|
|
|
|
Funny, I have a feeling you weren't taught with original code either. This is another example of someone thinking the op should be equally as skilled as the person responding. If you don't feel like spoon feeding you shouldn't be offering assistance all you do is add to the confusion.
|
|
|
|
|
Alisaunder wrote: Funny, I have a feeling you weren't taught with original code either.
You're right. I'm self-taught over the span over 30+ years. When I was learning most of my stuff, there was no internet, so I was pretty much on my own, reading as much as I could.
Alisaunder wrote: This is another example of someone thinking the op should be equally as skilled
as the person responding.
With coding skills, not at all. But the research skills and the ability to teach yourself something new? Oh, yeah. Those are basic skills you learn in school and apply to the coding job every day. If you want someone to spoon-feed you stuff all the time, you're not going to last very long. And there are a TON of people who come here looking for the spoon.
I give enough information to the OP so they can Google the problem themselves. In my humble opinion, new coders today have it much easier than I did learning this stuff.
|
|
|
|
|
Someone (I think it was here on CP) told me that as is as fast as is, so it's better to do
foreach(Control c in Controls) {
MdiClient mdi = c as MdiClient;
if(mdi != null) { ... }
}
... because you avoid the cost of the second cast.
|
|
|
|
|
There is only one cast being made on each iteration of the loop until the correct control is found. So it really doesn't matter which you use since the only speed difference (and it's a very minor one) would be the expense of the second cast on the inside of the if statement.
|
|
|
|