|
Before I respond to your specific question, I want to suggest to you that you need to study the basics about what Classes are in C#. Based on my experience with students, I believe you are not clear yet on the important difference between declaring/defining a Class, and creating an instance of a Class.
After you understand that, you can then understand what static Classes are, where the declaration/definition of the Class automatically creates a singular instance.
~
Yes, it is possible to:
1. define a Class within a Class:
using System.Windows.Forms;
namespace YourNameSpace
{
public class OuterClass
{
public OuterClass(int someInt)
{
SomeOuterInt = someInt;
}
public int SomeOuterInt { set; get; }
public void SayWhat()
{
MessageBox.Show("Outer What");
}
public class InnerClass
{
public InnerClass(int someInt)
{
SomeInnerInt = someInt;
}
public int SomeInnerInt { set; get; }
public void SayWhat()
{
MessageBox.Show("Inner What");
}
}
}
} You can then create either Class:
OuterClass outerClass = new OuterClass(42);
OuterClass.InnerClass innerClass = new OuterClass.InnerClass(24);
outerClass.SayWhat();
innerClass,SayWhat(); But, think about what this is: it is the equivalent of a recipe/blueprint for the construction of a Class that happens to have another recipe/blueprint inside it.
There is no real "dependency" between the two Classes at run-time: creating an instance of the OuterClass does not create an instance of the InnerClass. You cannot do this:
OuterClass outerClass = new OuterClass(42);
outerClass.InnerClass.SomeInnerInt = 108;
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Maybe I'm wrong ... but I understood the question that the enquirer wants to instance OuterClass inside OuterClass. I didn't tried that yet ... but in my opinion that isn't possible ...
|
|
|
|
|
Thanks Bill.
After using an example from a book I had a better understanding on an instance of a class.
Thanks also for the code example you provided.
This is my main question.
I know that this is possible
dante.displayAttributes();
But is this possible
game.inventory.getobject
(notice the use of two dots instead of one dot.
I consider inventory to be within a class.
Brian
|
|
|
|
|
That's not nesting classes.
What you're really describing is the game class is exposing a property called 'inventory'. That property may return an instance of some class that manages a characters items collection. The getobject method would be called on whatever that class instance is that was returned by the inventory property.
|
|
|
|
|
Brian, Virtually anything can be done, but, I'd like to see you get a good grounding in the fundamentals of OOP in C# .NET, so that in the future you will be able to distinguish between what might be done and what is commonly done to create useful programs.
Everyone here was a beginner at some point We've all struggled towards mastery of the fantastically rich tools that the FrameWork, the language, and Visual Studio offer.
In my experience, students often go through a phase of bewilderment as they seek to get oriented; often become dazzled by some aspect of the language, like dot-notation. That's okay for a while, but needs to be slowly eclipsed by focusing on fundamentals.
Please check out some other posts of mine here that relate to learning C#, and which include book (some free) recommendations: [^], [^], [^]
Let's see you connect the dots
cheers, Bill
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Hi Bill.
I wanted to know if C# was suitable for my purpose before I went too depply into learning this language, but what I've seen so far it looks like it might be what I'm looking for.
Last year I learnt Python, but while it's easy to program in it's slow and does not create compiled files that have an exe extension so that they're easy to run. You can create an exe using py2exe program but there's a lot of work in making the code ready but adding extra information to the code.
Also it's a fairly loose language and A="Tom:A=22 works without an error, so 'A' is not protected
So after considering Visual Basic Net which tends to add extra code "If..Then.. End If, etc I'm starting to like C#.
The next step is to get a better understanding of things such as Constructors, Destructors and Polymorphism.
Brian
|
|
|
|
|
To add to Bill's comments, your example looks more like accessing a property of a class, in which case you don't need to nest the classes:
public class Game
{
public Game()
{
Inventory = new GameInventory();
}
public GameInventory Inventory { get; }
}
public class GameInventory
{
public object GetObject()
{
return ...
}
}
...
Game game = new Game();
object x = game.Inventory.GetObject();
C# Guide | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I found different solutions to this sort of CRTP problem previously... but can't think of a way around it this time.
The main form used by my current project allows for moving and resizing even when it doesn't have a border. I have seen other people ask about this particular need before (it seems like a fairly common need for custom forms) and I have developed a better solution than what I have seen for answers online. I would like to provide a more generic solution than the one I am using currently for myself and others if possible so hence... my asking this prerequisite question beforehand.
I am needing to create several "controls" in my current project that have this same exact behavior so I want to write an inheritable class for all of them. Simple enough... just write a template that derives from Control. The problem is that none of the derived classes will look and perform like their actual base class in every other way without some way to use a CRTP. It would be nice not to have to write separate base classes for all the seperate possible control types, including forms. Is there a way to write a generic class to cover all controls that one would want to use? Something that effectively does what this would do if this were c++? (I realize that the where statement is c# but there are ways to accomplish the same basic idea in c++).
public class MovableControl<InheritedControl> : InheritedControl where InheritedControl : Control
{
}
In c# the above class definition doesn't compile because in .NET inheriting from a template parameter is not allowed (which is why I need an alternative solution.). Of course I will continue hunting on my own, or worst case, brute force it (by creating the separate classes) but I thought I would ask here in case someone already had an idea.
|
|
|
|
|
I will be posting this as a Tip/Trick or Article here in the future with comments and explanations, but, I'm in a rush right now, and don't have time to revise/comment my extended version of this, but, this should give you some ideas.
In a Form Load eventhandler, make some Controls movable like this:
button1.SetMovable();
textBox1.SetMovable();
panel1.SetMovable();
The code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace YOURNAMESPACE
{
public static class ControlMovableExtensions
{
private static Control currentControl = null;
private static Control currentContainer= null;
private static List<Control> MovableControls = new List<Control>();
private static Rectangle ClippingRect;
private static Rectangle ContainerRect;
private static Point lastGoodLocation;
private static Point nextLocation;
private static int mdx, mdy;
private static bool IsMouseUp = true;
private static bool UseClipping = false;
private static bool UseCapture = false;
public static void SetMovable(this Control control)
{
if (MovableControls.Contains(control))
{
throw new ArgumentException("control already movable");
}
MovableControls.Add(control);
control.MouseDown += ControlOnMouseDown;
control.MouseUp += ControlOnMouseUp;
}
public static void RemoveMovable(this Control control)
{
if (! MovableControls.Contains(control))
{
throw new ArgumentException("control is not movable");
}
control.MouseDown -= ControlOnMouseDown;
control.MouseUp -= ControlOnMouseUp;
}
private static void ControlOnMouseMove(object sender, MouseEventArgs e)
{
if (IsMouseUp) return;
nextLocation = new Point(currentControl.Left + e.X - mdx, currentControl.Top + e.Y - mdy);
if (ContainerRect.Contains(new Rectangle(nextLocation, currentControl.Size)))
{
lastGoodLocation = nextLocation;
}
currentControl.Location = lastGoodLocation;
}
private static void ControlOnMouseUp(object sender, MouseEventArgs e)
{
IsMouseUp = true;
currentControl.MouseMove -= ControlOnMouseMove;
if (UseClipping) Cursor.Clip = Rectangle.Empty;
if (UseCapture) currentControl.Capture = false;
currentControl = null;
}
private static void ControlOnMouseDown(object sender, MouseEventArgs e)
{
currentControl = sender as Control;
if (currentControl == null)
{
throw new ArgumentException("control is null");
}
currentContainer = currentControl.Parent;
ContainerRect = currentContainer.ClientRectangle;
lastGoodLocation = currentControl.Location;
mdx = e.X;
mdy = e.Y;
if (UseClipping)
{
ClippingRect = currentContainer.RectangleToScreen(currentContainer.ClientRectangle);
Cursor.Clip = ClippingRect;
}
if (UseCapture) currentControl.Capture = true;
currentControl.MouseMove += ControlOnMouseMove;
IsMouseUp = false;
}
}
}
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
modified 7-Mar-19 7:14am.
|
|
|
|
|
Interesting approach using extensions. That may work. The one problem is overriding the WndProc as that is the best way to detect resizing attempts. I supposed the override can call a static method... but that is a bit strange unless we can successfully use aggressive inlining. Perhaps we can combine our ideas and write the article together since my approach is very efficient and almost works just like an ordinary window. (There is a bit of a flicker when resizing upward and left but it still works well).
|
|
|
|
|
Hi, Yes, it does work
I am not sure why you are bringing in WndProc here, for me, use of WndProc is a last resort, and that's even more so now that .NET Core is evolving rapidly.
I use different techniques to handle the rare case when a user needs to arbitrarily re-size a Control at run-time.
I look forward to reading your article.
cheers, Bill
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Use a proxy. Move / resize the proxy; when done, copy the properties to the original target.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
That's an interesting approach, one that seems like what goes on with drag-drop.
In what kind of scenario would you use this rather than just move the Control ?
thanks, Bill
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
I actually am using a proxy system. However, the main window also uses the same (similar in the case of move) system since it is a border-less form. That is why I posted this topic to begin with. I want to write one set of code for both forms and controls.
|
|
|
|
|
Only numeric textbox
private void tbxTCKimlik_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(e.KeyChar >= 48 && e.KeyChar <= 57)) e.Handled = true;
if (e.KeyChar == Convert.ToChar(8)) e.Handled = false;
}
modified 6-Mar-19 9:05am.
|
|
|
|
|
Apart from being pretty poor code, what do you expect us to do with that?
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
What s the problem with codE ?
|
|
|
|
|
Undocumented, magic numbers, unnecessary else condition, doesn't work with all characters sets, difficult to reuse without copy'n'paste, can be bypassed with no effort to put non-numeric characters in the TextBox, trivial problem that has better solutions (including the use of standard controls), only works efficiently in app based code - it's a gawd awful solution for a web based project.
Even the TextBox name it's attached to violates C# naming conventions[^] ...
That's why I think it's poor quality code...
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Incidentally, I have need for a similar solution (except for my issue is with a .NET System.Windows.Forms textbox). I agree that he doesn't actually ask a question here so we are not sure how to help. However, since I am facing what appears to be a similar situation (from what I can tell...) I will try and interpret: he is probably saying that his editbox doesn't catch the backspace button. I have the same problem with an editbox that is for supplying a zip code. It works fine except that the backspace key is not accepted as a control key so it doesn't respond to backspace (the back/back delete key)
|
|
|
|
|
pr1mem0ver wrote: he is probably saying that his editbox doesn't catch the backspace button
if (e.KeyChar == Convert.ToChar(8)) Also, backspace and delete are not the same button, and have a different effect.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
Yeah... already tried that. It doesn't work either.
|
|
|
|
|
Then you have an error in your code
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
@pr1mem0ver Using a sub-classed TextBox, and its KeyPress event, 'Delete is not registered because it is a Control Key.
However, 'Delete will do the usual in such a TextBox.
If you start a new post here and post your current code with a description of what your goal is, and what's not working, I'll respond in detail.
cheers, Bill
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
modified 9-Mar-19 8:01am.
|
|
|
|
|
If you think you're posting that for the benefit of others, that code will only work with keyboards that are rooted in a Latin character set. Your code is limited to the straight numeric values in ASCII. Try that on a Chinese or Japanese keyboard and you'll see the problem with it.
It's also not built into its own control so it can easily be reused, which itself is easy enough to do.
There are other, much better ways to do this, but I don't have the time to go into it right now.
|
|
|
|
|
Thank you for comment. This is best what I can do. If you have better solution. Please share it.
|
|
|
|