|
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.
|
|
|
|
|
Yes, it is pretty minor. I have started writing my code in that way since then, though.
|
|
|
|
|
Alisaunder wrote: And yet neither of you are displaying an alternative that is better? I think the absence of code here is not the result of any 'negative intention:'
It's just obvious that the best practice here is to enumerate the controls on the Form [1], test each one using the 'Is operator, and, when the MdiClient Control is found, then cast it from Type Control back to its 'native Type, 'MdiClient ... at which point you can have your way with it.
private MdiClient theMDIClientControl;
foreach (Control theControl in this.Controls) [2]
{
if (theControl is MdiClient)
{
theMDIClientControl = theControl as MdiClient;
break;
}
}
if (theMDIClientControl != null) theMDIClientControl.BackgroundImage = mdiBackGround; [1] see my response to Dave K. above[^] confirming why it is absolutely necessary to enumerate the Controls on the Form.
[2] Seems a reasonable assumption the MdiClient Control will always be in the top-level Form Control Collection: hence no need for a recursive search
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
And in some rare cases it may not be in the top-level Form. Also adding Try and catch is error controlling which I don't care who you are is still considered good practice, otherwise you end up with crashing code that nobody can debug. Once you have a complete project you can remove The error handling code to streamline the application. But to say it's not good practice to include it is in my opinion really stupid and asking for trouble.
|
|
|
|
|
Alisaunder wrote: Also adding Try and catch is error controlling which I don't care who you are
is still considered good practice
Only if used appropriately. If this little block is coded up correctly, you won't have a need for a try/catch block at all.
If I had to use a try/catch block, it wouldn't be in the manner than you copied from MSDN. It would have been outside the foreach or even in the caller and not this method and still used the if statement to test the control type.
|
|
|
|
|
No, you're wrong. Correct exception handling is good practice, yes. Using exceptions where there is a well documented non-exception path is not, because exceptions are expensive and slow. You should use exceptions for exceptional cases, not as part of normal flow control.
|
|
|
|
|
Alisaunder wrote: Also adding Try and catch is error controlling which I don't care who you are
is still considered good practice
You clown....and empty catch block is NOT a valid error handling technique...as others have pointed out to you, it's not what exceptions are there for...it's just LAZY to catch and ignore an exception, since you can check before hand if it's not a valid item...
Alisaunder wrote: otherwise you end up with crashing code that nobody can debug
Cobblers....you have heard of a debugger yes?
Alisaunder wrote: Once you have a complete project you can remove The error handling code to
streamline the application
Seriously? Remove error handling once it's complete? Oh dear god....
C# has already designed away most of the tedium of C++.
|
|
|
|
|
Hi, I don't think you deserve to be cast into the outer darkness of the dreaded one-vote here, because you were, I think, sincerely trying to respond to the OP's question.
And, whether the code you provided leads to gnashing of teeth, or not, it does work.
But, may I suggest, in the future, you provide a link to the MS docs, or other sources, code examples are taken from.
best, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
I don't see where you problem is : if you cannot see the background of your MDI parent, it is because there is another object above it (its child) which is masking the main form.
So, you can change the background color of the main form as you want, your change will be applied but you will not see it as there is still the same child object above it.
Why don't you change the background color of the MdiClient control, so ?
And, please, reserve the use of 'pre' tag for actual code.
No memory stick has been harmed during establishment of this signature.
|
|
|
|
|
You normally can't see the background of an MdiParent form. It's being covered byt eh MdiClient control which is Dock = Full over the entire form.
|
|
|
|
|
Does this[^] article help?
/ravi
|
|
|
|
|
In a container form I have menu and buttons to open their forms.
Here I am facing a problem when I open any form these buttons and lables come over newly opened form.
Please guide me how I can manage this issue? I want to open a new form and keep these container form's controls in back ground of it.
|
|
|
|
|
|
This happens because you put controls in the client area of the MdiParent form (the darker area of the form).
You cannot do that unless you either want those controls to be over the top of all of your MdiChild forms or you have to resize the MdiClient control that's on the MdiParent form. The problem is, you can't do that are designtime. It has to be done as runtime.
You have to iterate through the MdiParent forms Controls collection, looking for a control of Type MdiClient, then you can set its Dock property to False and resize it to what you need to make room for your controls, and lastly set it the Anchor property appropriately to maintain that layout.
|
|
|
|
|
In this recent QA thread[^], is an example of creating a "class factory" based on an Interface, and then making classes that inherit from that Interface, and then, in the factory method, returning an instance of one of the inheritors cast to the Interface type.
I had set out to see, before reading Abhinav's comment on this thread, later followed by a code example, if I could achieve the same thing via use of an Abstract class definition, and, to my surprise, found that I could.
The curious thing being that I actually believed my code did not work ... until I saw Abhinav's code, and then went into my code, and set a break-point, and found I was indeed returning "pre-cast" objects from my factory method in the same way the use of the 'interface technique' would do
So, why am I raising a question here ? Because: I am curious what the implications of making an implementation of a "factory class" based on using an Abstract class rather than an Interface are: is it a "bad practice," is it ever preferred as a technique over using an Interface ?
You can see the tested C# WinForms code for the 'abstract' based factory class solution here[^], and I will truly appreciate any comments, or guidance.
thanks, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
Hi Bill,
this is how I see the matter:
1.
when you decide to use a factory, it tells me you want to be able to get an instance of a number of possible types, where the exact type will depend on some parameters; and you also have good reasons to put the creation of those different instances in a common method because, to you, they share some common behavior, and its that behavior you're interested in.
Example: you could want a factory that returns either a Monkey or a Lion ; you would not want a factory that either creates a Monkey or a ProgrammingLanguage .
2.
The common behavior is the only thing that matters to you; if you want Animal behavior, the Monkey-and-Lion example would be good, and both Monkey and Lion could inherit from Animal. Whether the inheritance is direct or distant (e.g. through Mammal or Quadruped or QuadrupedMammal ) is irrelevant; the base class possibly being abstract doesn't matter either.
3.
As always in inheritance, a number of languages (all .NET, Java, ...) don't support multiple inheritance, however they offer a cheap almost-replacement (arguable) and that is an interface. So in a factory, if all the Monkeys and Lions ever do for you is walk, then it would be cheaper (i.e. less restrictive, and not consuming the single inheritance) to have Monkeys and Lions implement IWalk , so whatever the factory returns, you can make it Walk() . Much simpler than having the code that calls the factory worry about the exact genealogy of your Animals, Mammals, Quadrupeds, and what have you.
Conclusion: IMO factories should return an interface, unless you're pretty sure about the (stability of the) class hierarchy. It is in fact a weaker form of the "separation of concerns" principle.
PS: you're right, way too interesting to be handled in Q&A
|
|
|
|
|
Nice explanation
No comment
|
|
|
|
|
Thanks Mark
|
|
|
|
|
That's a most eloquent, and intellectually satisfying answer, thanks, Luc !
If I interpret your words correctly (big IF), then I am inclined to interpret this type of use for interfaces ... beyond the obvious use as a way to establish a 'contract' that specifies what implementors of the interface must provide ... is to model shared 'behavior:' where modeling is-a, or inheritance relationships, is not an absolute requirement. As you say: "weaker form ... of separation of concerns." And more efficient ? At the least, more logically "lean and mean."
I do note the MS docs talk about interfaces in terms of expressing "related functionalities." And proscribes Interfaces as "The interface itself provides no functionality." And, of course, an Interface requires implementors to implement everything defined in the Interface.
While I am still a bit puzzled about what the 'abstract' class was intended for ... by its designers ... compared to just inheriting from a base class ... other than that it, indeed, does express is-a, or hierarchy: that's something I can certainly pursue in my books and on-line.
Since the abstract class does, as interface does, demand its consumers implement things it (optionally) wants to 'use' (via 'override'), and can, as explored here, function as a factory object; the question arises in my head as to what is a 'modal case' in which it would be 'crystal clear' that using 'abstract' as a basis for a factory class is 'best practice' ?
One clear difference that stands out: an abstract class can contain, as in my code-exploration, a static method: an interface cannot.
So, maybe, an interface is a schematic, and using abstract class as a factory object is more equivalent to a tool-chest with a schematic inside, as well as actual ready-to-go tools which can easily be modified on-the-job ?
from a happy Monkey to a wise Lion, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|
Hi Bill,
I agree with what you said. And I'll phrase things differently once more:
an interface indeed is a contract: IWalk could be defined as "offers a public Walk() method". And that is all it is, there is no data defined, and no executable code whatsoever: no static methods, no instance methods. So it is just a spec for the implementer. And it can hide (or ignore) a lot; one of the nicest examples is IEnumerable (generic or not), as is required by foreach . Without knowing anything about your collection, foreach can enumerate all elements of your collection, whether an array , an ArrayList , a List<T> , a string of characters, etc.
A base class, abstract or not, can hold both data members and executable code; so it can provide real functionality (actual methods) as well as helper methods, etc.
An abstract class is a more restricted base class, in that the abstract methods must be replaced (overridden) by its inheritors.
So if you want Monkey and Lion classes, they could inherit from Animal . If you don't ever want to see a mere instance of Animal , then make that class abstract; if you want, or don't mind, a new Animal() , then don't make it abstract.
If Monkey and Lion were to be able to Hunt() , while deriving from an abstract Animal class, you would have to have each of them provide their own Hunt() method, which could rely on some shared methods in the base class.
In summary:
1. a class that inherits from a base class emphasizes the "is a" relationship, and therefore was willing to devote the single inheritance right it has to express that; it may or may not re-implement known behavior.
2. s class that inherits from an abstract class emphasizes the "is a" relationship, but also prevents the creation of non-specialized objects; the price to pay is you need to provide the specialization code in each of the descendants.
3. a class that implements an interface emphasizes the "knows how to" relationship, it does not exhaust the inheritance rights, however it must implement everything it promises it knows how to do.
More comments:
1. the set of available choices may not be perfect, but it is adequate. One could even live without abstract , leaving it out of the language spec (or the app) just opens the door to possibly unwanted situations (e.g. unspecified Animals); .NET would not be viable without interface .
2. every class can implement any number of interfaces, see e.g. the List<T> class which implements a lot of them.
3. typically the API of an interface is rather small, whereas the API of a class could be very big. There is an OO guideline that says something like: try to describe your interfacing specs in many, small interfaces, rather than in few, big interfaces; obviously nobody wants them so small that they become useless on their own, e.g. with collection-like functionality Add() and Remove() would normally be part of the same interface.
|
|
|
|
|
I have done that with abstract base classes in the past, but I prefer to use interfaces now. Interfaces are more flexible, they don't impose a relationship on the classes.
|
|
|
|
|
PIEBALDconsult wrote: Interfaces are more flexible, they don't impose a relationship on the classes. If you care to expand on this interesting comment, I'd be very interested to know what the "costs" were of having the "relationship on the classes."
And, if you care to comment, why, in the past, did you use abstract classes rather than just inheriting from a base class ?
thanks, Bill
"Last year I went fishing with Salvador Dali. He was using a dotted
line. He caught every other fish." Steven Wright
|
|
|
|
|