|
Note: code examples shown here are created in VS 2015, compiled against FrameWork 4.6.
Big picture: object design best practices
1. Nested Classes in C# .NET:
As you know, C#, unlike Java, has no mechanism for a nested Class to refer to the instance of the "outer class" that wraps/contains it ... well, yes, the inner Class instance will have access to private members of the outer class instance... if it has a valid reference to the outer class instance, a unique feature. So we can write this:
namespace Whatever
{
public class OuterClass
{
private DateTime DateTm { set; get; }
public OuterClass()
{
DateTm = DateTime.Now;
}
public class InnerClass
{
public OuterClass InnerOuter { set; get; }
public InnerClass(OuterClass outer = null)
{
InnerOuter = outer;
}
}
}
} And, yes, if we create a new instance of OuterClass, and then create an instance of InnerClass, passing the instance of OuterClass to the ctor of InnerClass: then, InnerClass has access to the private property 'DateTm in OuterClass ... if the InnerClass has no reference to an OuterClass, then, as expected, it cannot access the private Property. You could also look at the option to define a nested Class as private, in which case, obviously, the outer class can inject a reference to itself into the inner Class. While I have never seen code that gets a big benefit from using nested classes, I assume there is some scenario in which that structure is beneficial, I just haven't come across it.
2. Challenge of object injection into a Class which may "stand alone," or may be a child element of another Class, or, a collection of the same Class (child collection).
2.a. Context
I mention this to establish a context for my real question here, which is about finding a "clean" way to implement a hierarchy where the "child objects" have references to their "parent," and to the overall context ("tree") in which they are elements. At the same time, the challenge includes finding a way to allow the user to create a child element that "stands alone," that does not have a reference to its Parent or Tree ... until the user adds the child element to its "child element collection."
Yes, you can see exactly such a paradigm in the WinForms TreeView, where you can create a new TreeNode that exists "independently" of any TreeView, or TreeNodeCollection. fyi: a WinForm TreeNode contains properties of Type TreeView, and TreeNodeCollection. A WinForm TreeNodeCollection does not contain a 'TreeView Property, and has no ctor ... it's a sealed class.
2.b Code
Here's a code-sketch in which I deliberately avoid using 'TreeView nomenclature to try and keep assumptions being made based on what I/you may know of tree view controls you use now:
using System.Collections.Generic;
namespace Whatever
{
public class OuterClass
{
public List<InnerClass> AllInners { set; get; }
public OuterClass()
{
AllInners = new InnerCollection();
}
}
public class InnerCollection : List<InnerClass>
{
public new void Add(InnerClass inner)
{
if (inner.MyOuter != null) inner.MyOuter.AllInners.Add(inner);
base.Add(inner);
}
}
public class InnerClass
{
public OuterClass MyOuter { set; get; }
public InnerClass Parent { set; get; }
private InnerCollection _childInners;
public InnerCollection ChildInners
{
get
{
if(_childInners == null) _childInners = new InnerCollection();
return _childInners;
}
}
public string Text { set; get; }
public int Level { set; get; }
public InnerClass(string text = "", InnerCollection inners = null, InnerClass parent = null, int level = -1)
{
Text = text;
if (inners != null) _childInners = inners;
Parent = parent;
Level = level;
}
}
} With this code, you can (obviously) create a InnerClass element that "stands alone:"
Whatever.InnerClass testInner = new WhateEver.InnerClass("test1");
Console.WriteLine("inner: {0} parent: {1} tree: {2} innercollection: {3}",
testInner.Text,
testInner.Parent.NullToString(),
testInner.MyOuter.NullToString(),
testInner.ChildInners.NullToString());
So, here's the "unfinished business:"
0. how to get a valid reference to the Outer (tree) into the InnerCollection class when you are adding a new InnerClass to the InnerCollecton class of a InnerClass that has been added to a InnerCollection that has been added to the Outer (tree).
1. how to do this without using reflection.
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
How about something like this:
public interface IChild<TParent>
{
void SetParent(TParent parent);
}
public class ChildCollection<TChild, TParent> : System.Collections.ObjectModel.Collection<TChild> where TChild : IChild<TParent>
{
public ChildCollection(TParent parent)
{
Parent = parent;
}
public TParent Parent { get; }
protected override void InsertItem(int index, TChild item)
{
item.SetParent(Parent);
base.InsertItem(index, item);
}
protected override void SetItem(int index, TChild item)
{
Items[index].SetParent(default(TParent));
item.SetParent(Parent);
base.SetItem(index, item);
}
protected override void RemoveItem(int index)
{
Items[index].SetParent(default(TParent));
base.RemoveItem(index);
}
protected override void ClearItems()
{
foreach (TChild child in Items)
{
child.SetParent(default(TParent));
}
base.ClearItems();
}
}
public class OuterClass
{
public OuterClass()
{
AllInners = new ChildCollection<InnerClass, OuterClass>(this);
}
public IList<InnerClass> AllInners { get; }
}
public class InnerClass : IChild<OuterClass>, IChild<InnerClass>
{
public InnerClass()
{
ChildInners = new ChildCollection<InnerClass, InnerClass>(this);
}
public OuterClass MyOuter { get; private set; }
public InnerClass Parent { get; private set; }
public IList<InnerClass> ChildInners { get; }
public string Text { get; set; }
public int Level { get; set; }
protected virtual void SetParent(OuterClass parent, bool fromCollection)
{
if (ReferenceEquals(MyOuter, parent)) return;
var oldOuter = MyOuter;
if (oldOuter != null)
{
MyOuter = null;
oldOuter.AllInners.Remove(this);
}
MyOuter = parent;
if (parent != null && !fromCollection)
{
parent.AllInners.Add(this);
}
foreach (var child in ChildInners)
{
child.SetParent(parent, false);
}
}
void IChild<OuterClass>.SetParent(OuterClass parent)
{
SetParent(parent, true);
}
protected virtual void SetParent(InnerClass parent)
{
if (ReferenceEquals(Parent, parent)) return;
var oldParent = Parent;
if (oldParent != null)
{
Parent = null;
oldParent.ChildInners.Remove(this);
}
Parent = parent;
var newOuter = parent != null ? parent.MyOuter : null;
SetParent(newOuter, false);
}
void IChild<InnerClass>.SetParent(InnerClass parent)
{
SetParent(parent);
}
}
This should then let you compose the tree however you see fit:
var outer = new OuterClass();
var root = new InnerClass { Text = "A", Level = 0 };
var child = new InnerClass { Text = "A.1", Level = 1 };
var grandchild = new InnerClass { Text = "A.1.i", Level = 2 };
child.ChildInners.Add(grandchild);
root.ChildInners.Add(child);
outer.AllInners.Add(root);
root.ChildInners.Add(grandchild);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
08:49 Tuesday GMT + 7 (DST not used here)
Fascinating code, really appreciated; it's going to take me some time to try and understand your use of interfaces and where constraints here. After a first pass over the code, I think it points me in s direction I was planning to explore, which is to handle setting 'tree and 'nodecollection parameters of an 'innerclass in the 'nodecollection code.
On my list to examine is, possibly, using 'CallerMemberInfo in the 'nodecollection class.
22:49 Monday ... Thanks, Richard, I look forward to studying your code tomorrow (GMT +7) after (hopefully) some too long postponed sleep.
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
modified 10-Oct-16 21:59pm.
|
|
|
|
|
please help me to read mbr
i can not to read this
|
|
|
|
|
|
Google is your friend: Be nice and visit him often. He can answer questions a lot more quickly than posting them here...
A very quick search using your subject as the search term gave nearly 400,000 hits: Google: "how to read MBR in C#"[^]
The top link is on MSDN: Read MBR Sectors[^]
In future, please try to do at least basic research yourself, and not waste your time or ours.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I made app in C# that convert resistor value to color codes.
How to make support for 5 band and 6 band resistor and how to make support for mΩ,uΩ,nΩ,pΩ ?
What should I add? http:
|
|
|
|
|
The sixth band can be ignored like the tolerance band because it is an additional indicator for reliability or temperature coefficient. So handle it like a 5 band code. For 5 bands just enhance the code to support one more digit. With conversions from value to bands you should print out the result for 4 and 5 bands.
The smallest possible value that can be represented by color codes is 1 m / 0.1 m for 4 / 5 band codes. So there is no need for other units then mOhm. Even values smaller than 1 Ohm can be shown in Ohms because values below 0.1 Ohm are rather seldom with band codes. Resistors with small value (shunt resistors) usually have the value printed on the case.
|
|
|
|
|
Do I just need to add something below this:
Color.FromName(colours[res[0] - '0']);
Color.FromName(colours[res[1] - '0']);
Color.FromName(colours[third != 0 ? third : res.Count() - 2]);
|
|
|
|
|
No.
With one more digit you have to adjust the multiplier too.
BTW: You should post code here rather than providing an external link.
I did not checked if your code is working. But if so, you should have no problems to extent it to support one more digit. I would create two different functions to get the colors for 4 and 5 bands which are called after parsing and checking the input.
|
|
|
|
|
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.Text == "4")
{
if (textBox1.Text == "0")
MessageBox.Show("Otpornost mora biti veca od nule", "Otpornost", MessageBoxButtons.OK, MessageBoxIcon.Error);
var colours = new string[] { "Black", "Brown", "Red", "Orange", "Yellow", "Green", "Blue", "Violet", "Grey", "Silver", "Gold" };
var factorDictionary = new Dictionary<char, int>() { { 'R', 1 }, { 'K', 1000 }, { 'M', 1000000 }, { 'G', 1000000000 } };
string res = string.Empty;
while (string.IsNullOrEmpty(res))
{
res = textBox1.Text;
}
var lastChar = res.Last();
var isUnitCorrect = factorDictionary.ContainsKey(lastChar);
var value = res.Substring(0, res.Length - 1);
var isValueCorrect = !value.Any(x => !char.IsDigit(x));
if (isUnitCorrect && isValueCorrect)
{
int mul = factorDictionary[lastChar];
double val = double.Parse(value) * mul;
int third = 0;
if (val < 1)
{
val *= 100;
third = 9;
}
else if (val < 10)
{
val *= 10;
third = 10;
}
res = val.ToString();
if (res.Count() > 11)
MessageBox.Show("Invalid value");
else
{
label15.BackColor = Color.FromName(colours[res[0] - '0']);
label16.BackColor = Color.FromName(colours[res[1] - '0']);
label17.BackColor = Color.FromName(colours[third != 0 ? third : res.Count() - 2]);
}
}
else
MessageBox.Show("Invalid value!");
}
}
|
|
|
|
|
I have problem when I enter value in uΩ,nΩ or pΩ.When I enter mΩ it is working good !!!
https://postimg.org/image/y6q4bw64d/
|
|
|
|
|
How to show closest standard value and closest standard color for resistor?
https://postimg.org/image/4gbzvpea5
https://postimg.org/image/q80yvq1uf
|
|
|
|
|
hi, i want to copy a text when i right click on a text in any windows anywhere, like babylon.
please help me and take me a simple code to do it?
|
|
|
|
|
What have you tried?
Where are you stuck?
And what does an ancient city have to do with it?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
|
Firstly, I doubt it will do what you want: the "text" it is talking about is probably the title, rather than the content. Windows can draw anything they like into themselves, it doesn't have to be related to any string based data.
Secondly, there is no "simple code" for this job: it's complicated for a reason, which is that it's a complicated task! I suspect that for what you want, it'll be even more complicated becuase you are goign to have to get involved with OCR and all sorts.
And thirdly, Babylon is an ancient city: https://en.wikipedia.org/wiki/Babylon[^] - and an important one.
It's also a browser hijacker toolbar, a former Iraqi project for the construction of superguns, a darknet market seized by law enforcement in July 2015, a design for space stations on TV, a strong and powerful (yet corrupted and immoral place) in Rastafarian religion, ... it may be a dictionary as well, but that's not its major claim to fame!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
my english is not good. please taked easy
no i dont want use of OCR i want just move the cursor on the one text and press right click And the text to be sent to a TextBox That 's it!
Ohh It is clear that this city is famous!! But my mean was Babylon Program.
|
|
|
|
|
It's not as simple as that: it the control is part of your app it's simple, but if it isn't then there may not be any accessible string component. Windows doesn't work like that - for example, Word is not a huge multi line text box, it draws a "chunk" of text from a tree of non-displaying class items which may or may not expose any text internally, much less externally.
What you want to do is not simple: it's extremely complicated and may only be possible if you take a "picture" of the window and use OCR to convert it to text.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Thank, So How to Take a pic when i right click on a control? And Convert it a text with OCR? what library should i use for it?
modified 10-Oct-16 1:57am.
|
|
|
|
|
Your link doesn't work and we are not a write code to order service.
|
|
|
|
|
In C# 2005, I did not find lineControl, Have I be installed the wrong ? I want to have control I install them like ?
|
|
|
|
|
What are you talking about? I have no idea which LineControl you are talking about: what namespace should it be in, what does it do, how are you trying to use it? What environment is your app supposed to run for?
Remember that we can't see your screen, access your HDD, or read your mind.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
If you mean in WinForms ...
- Add a Label control to your form.
- Set Label Text to empty.
- Set BorderStyle to Fixed3D.
- Set AutoSize to false.
- Set Height to 2 (most easily accomplished by typing 2 into the Size/Height field under Label Properties).
|
|
|
|
|
Hi,
I am totally new to ASP.NET. Please help me to create a project to store persistent data.
Thanks
|
|
|
|
|