|
Thanks for the reply I left the Person class as it is but changed Program:
class Program
{
delegate void DictionaryDel();
static Dictionary<string, DictionaryDel> _action;
static PersonManager _personManager;
static void Main()
{
_personManager = new PersonManager();
LoadActions();
_action["1"]();
Console.Read();
}
static void LoadActions()
{
_action = new Dictionary<string, DictionaryDel>();
_action.Add("1", _personManager.DumpAllToConsole);
}
}
modified on Sunday, May 2, 2010 8:01 AM
|
|
|
|
|
Good call on writing LoadActions -- now can you make a class to encapsulate the menu options?
Menu menu = new Menu ( _personManager ) ;
|
|
|
|
|
This is the code that I have created so far, your comments are very helpful!
class Program
{
static void Main()
{
PersonManager personManager = new PersonManager();
Menu mainMenu = new Menu(personManager);
mainMenu.LoadActions();
mainMenu.Display();
Console.Read();
}
}
class Person
{
public Person(string forname, string surname, string title)
{
ForName = forname;
SurName = surname;
Title = title;
}
public string ForName { get; set; }
public string SurName { get; set; }
public string Title { get; set; }
public override string ToString()
{
string fullName = string.Format("Name :{0} {1}\nTitle {2}", ForName, SurName, Title);
return fullName;
}
}
class PersonManager
{
private readonly List<Person> _personList;
public PersonManager()
{
_personList = new List<Person>(10)
{
new Person("James", "x", "Prog"),
new Person("Claire", "y", "Illu")
};
}
public void DumpAllToConsole()
{
foreach (Person p in _personList)
{
Console.WriteLine(p.ToString());
}
}
}
class Menu
{
private readonly PersonManager _personManager;
private delegate void DictionaryDel();
private Dictionary<string, DictionaryDel> _action;
public Menu(PersonManager personManager)
{
_personManager = personManager;
}
void GetInput(string input)
{
if (_action.Count == 0) return;
if (!_action.ContainsKey(input)) return;
_action[input]();
}
public void LoadActions()
{
_action = new Dictionary<string, DictionaryDel>
{
{"1", _personManager.DumpAllToConsole}
};
}
public void Display()
{
Console.WriteLine("Press 1 to display all students or 2 to quit");
string input = Console.ReadLine();
GetInput(input);
}
}
Is there anything else I should think about? Thanks !
...For some reason turning "Encode "<" (and other HTML) characters when pasting" on or off does not allow me to show the dictionary generic structure
modified on Sunday, May 2, 2010 12:46 PM
|
|
|
|
|
(Especially for the automatic properties (or whatever they're called).)
Not much else:
Maybe GetInput should be named DoAction instead?
I would likely call the LoadActions from the constructor.
I would have a while loop in Display.
You may also consider creating an interface from the PersonManager so the Menu can be used with other types of manager.
Come to think of it, maybe the Manager should be generic -- Manager<Person>.
|
|
|
|
|
Thanks again, I have implemented your advise and I can see that it is a much more manageable way that what it originally was, even though there is allot more work involved it does pay off!
class Program
{
static void Main()
{
Manager<Person> personManager = new Manager<Person>();
personManager.Add(new Person("James","x","Soft"));
personManager.Add(new Person("Claire", "y", "Illu"));
Menu mainMenu = new Menu(personManager);
mainMenu.Display();
}
}
class Manager<T>
{
private readonly List<T> _managedList;
public Manager()
{
_managedList = new List<T>(10);
}
public void DumpAllToConsole()
{
foreach (T p in _managedList)
{
Console.WriteLine(p + "\n");
}
}
public void Add(T input)
{
if (input.Equals(null)) return;
_managedList.Add(input);
}
public void Remove(T item)
{
if (!_managedList.Contains(item)) return;
_managedList.Remove(item);
}
public List<T> GetCopyOfList()
{
List<T> list = new List<T>(_managedList);
return list;
}
}
class Menu
{
private readonly Manager<Person> _personManager;
private delegate void DictionaryDel();
private Dictionary<string, DictionaryDel> _action;
private bool _running = true;
public Menu(Manager<Person> personManager)
{
_personManager = personManager;
LoadActions();
}
void DoAction(string input)
{
if (_action.Count == 0) return;
if (!_action.ContainsKey(input)) return;
_action[input]();
}
void LoadActions()
{
_action = new Dictionary<string, DictionaryDel>
{
{"1", _personManager.DumpAllToConsole},
{"2",(() => _running = false)}
};
}
public void Display()
{
while (_running)
{
Console.WriteLine("Press 1 to display all students or 2 to quit");
string input = Console.ReadLine();
DoAction(input);
}
}
}
Thanks again !
Also on a side note, I have just finished reading "The pragmatic programmer, from journeyman to master" and it talks about "orthogonality" which I am positive is the end result from the help I have received !
|
|
|
|
|
It's turning out better than I thought.
In Add, I would use a simple if ( input == null ) (this isn't Java).
Yeah, the lambda seems good there.
GetCopyOfList is a good idea, but look into list.AsReadOnly() to see if it might be what you want there.
I would still argue for an Interface that the Menu class requires -- that way it can (theoretically) be used with different types of Manager.
So far I see no need to make Menu be generic, but you may consider it.
thebuzzwright wrote: "orthogonality"
That's one of the (few) things I remember from college.
thebuzzwright wrote: even though there is allot more work involved it does pay off
It certainly can. It may not in this case, but having experience in how to do this sort of abstraction should pay off when it's really needed later.
|
|
|
|
|
Thanks again "PIEBALDconsult" you have helped me allot !
I don't feel the need to show the code as its just minor changes but:
1 - I added a IMenu interface which can "Display" so that I can derive new menu's for other situations.
2 - Menu inherits IMenu and I replaced " Menu mainMenu = new Menu(personManager);" with " IMenu mainMenu = new Menu(personManager);" so that I can use different menu's.
3 - I decided to switch the List<t> with an IList<t> so that I can use the "AsReadOnly()" method as I don't need to modify the contents.
4 - For the "Add" method: "if (input != null) ManagedList.Add(input);" looked better for me.
Final thoughts: I could apply the strategy pattern to IMenu so that it encapsulates its behaviour if needed, but this project was to show manageable code, and I think that would make it more complicated and unnecessary
Thanks again!
|
|
|
|
|
|
Just out of curiosity - Where do you attend and what level of student are you currently?
"I need build Skynet. Plz send code"
|
|
|
|
|
Alaric_ wrote: Where do you attend and what level of student are you currently?
I am a college (UK) student on a final year of a BTEC National Diploma in Computing. University this year to study computing hopefully
Why the curiousness ?
|
|
|
|
|
I have some code that creates an image, and renders some text to it. In a winform app, this results in a reasonably attractive image. However, in Asp.Net, the very same code results in a very ugly image (the stroke width is uneven, and the anti-aliasing is just barely noticable). Can anyone explain why this happens, and even better, a provide solution?
If you want to try it yourself, here's the code:
Bitmap bmp = new Bitmap(60, 30, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.Transparent);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
g.CompositingMode = CompositingMode.SourceOver;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
Font font = new Font("MS San Serif", 17, FontStyle.Regular, GraphicsUnit.Pixel);
Size textSz = TextRenderer.MeasureText(title, font);
int x = (int)((bmp.Width - textSz.Width) * 0.5);
int y = (int)((bmp.Height - textSz.Height) * 0.5);
TextRenderer.DrawText(g, title, font, new Point(x, y), Color.Black );
bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
MemoryStream ms = new MemoryStream();
bmp.Save(ms,System.Drawing.Imaging.ImageFormat.Png);
Byte[] buffer = new Byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, (int)(ms.Length));
Response.ContentType = "image/png";
Response.BinaryWrite(buffer);
Response.Write(title);
bmp.Dispose();
g.Dispose();
On the first line of code above, I had to fully qualify the last parameter in the WinForms app
(System.Drawing.Imaging.PixelFormat.Format32bppArgb )
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
Hi John, I think I have a partial answer for you: within a WinForm app, when you create a bitmap and then a Graphics from that, you get a Graphics that is compatible with your screen, so e.g. you could use MeasureString and get (pretty) accurate predictions for when you are going to draw some text in the Form.Paint handler.
AFAIK it does so by guessing which monitor you are on (when you have more than one that is). I never did any such thing in ASP.NET, I guess it does not have a (relevant) monitor around for you, so its properties could be way off; you might have a look at DpiX and DpiY (they are getters only!).
I don't know the solution right now; a little Google action pointed me here[^], maybe that helps.
|
|
|
|
|
He's not doing anything I'm not doing (and I'm doing even more). I've tried everything from a minimalist approach to full on high-quality settings, and nothing seems to affect the appearance of the image. Even Silverlight/WPF does a better job at rendering text...
I'm getting kind of annoyed at the whole thing...
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
Here is one idea: replace Transparent by White, just to see if that gives decent quality. I never trust Windows and transparency, it holds too many surprises.
|
|
|
|
|
Even if it displayed better, I need the background to be transparent.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
IMO making a little step sidewards is often useful in a debug session, even when it violates functional specs.
|
|
|
|
|
At this point, I'm tempted to just create the graphics with photoshop and call it a day.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
Well, it does in fact ONLY happen when I use g.Clear(Color.Transparent) . That's a real pisser because now I have to do a screen cap of the gradient background we use in the Silverlight app so I have a non-transparent image to render the text onto. What a pain in the ass... and all because a) Silverlight's element rotation f*cks up your layout, and b) it doesn't allow you to build images on the fly.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
From everything I read about it over the years, I gathered transparency on Windows is a PITA. I try and stay away from it as much as possible.
Thanks for reporting.
|
|
|
|
|
I've observed that it works fine in Winforms, but it sucks in asp.net
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
you may want to repost in ASP.NET forum then; and probably add a sample of each.
Did you notice anything different in the properties of both Graphics objects? From what you told so far, it isn't clear to me yet whether this indicates a bug or something you overlooked.
|
|
|
|
|
Complaints are many regarding he quality of text rendered on a transparent bitmap. The one thing I haven't tried yet is creating a transparent bitmap disk file, loading that in the asp.net page code behind, and rendering text on it. I can tell you that creating the (transparent) bitmap in code and rendering text onto it creates a crappy looking image. IMHO, it's a bug.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
In the interest of being able to say that I "tried everything", I created a png file that was nothing but a transparent background, as well as one that was nothing but a white background. Rendering text on the transparent file looked just like it did as if I had created the whole thing in memory - in other words, crap. The white png file resulted in perfectly anti-aliased text.
I just don't understand...
EDIT ===========
I also created a new white image that had the transparent color set to white. This generated a better image, but not NEARLY as good as having some sort of color on the bitmap.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
modified on Saturday, May 1, 2010 3:22 PM
|
|
|
|
|
|
Luc Pattyn wrote: there are two ways to try and achieve transparency; one is by using the alpha channel, that should allow a blend, so anti-aliased stuff can result in semi-transparent pixels; the other is by setting apart a special color which will be treated as transparent later on; blending here fails as the result is different from the one (or few) special colors.
I tried it both ways - neither result was acceptable, but the transparent color version was the best of the two.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|