|
Not exactly the answer to your question, but if add a document to your application you can replace your RichTextBox with a PrintPreviewControl, you can do any sort of layout you wish. Simultaneously, you can go from printPreview to real printing and it will keep the layout.
The drawing tools will allow you to just plain go crazy with elaborate formatting/shading/lines, etc, if you've a notion to.
At least that's how I do it.
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"How do you find out if you're unwanted if everyone you try to ask tells you to go away?" - Balboos HaGadol
|
|
|
|
|
I will have to check that out... I haven't done much with PrintPreviewControl. I'll have to research some more information about it.. thanks.
|
|
|
|
|
I was wondering.. what do you mean add a document? I still have to take the information and write it to a document? Do I do that then load the document in the printpreviewcontrol and then do editing?
|
|
|
|
|
Without going into the whole document interface thing in any detail:
You need to add a printDOcument object to your application. You write to it through its Graphics object.
Now, if you create a printPreviewControl (or dialog), it allows you (check the properties) to add a document (which is in its select list if you click the blank box). What this connection does is tell the preview which document to look at [you could use the same printPreview for multiple documents by changing that assignment at RT).
Anyway, you need to explore this, and some examples, but basically, you can write to the document anywhere, in any order, with various pens (thickness, linestyle, color, ...), brushes, fonts, lines, shapes. After a break-in period, you can do shading, too. Also, add graphics.
Much "richer" than the rich text box: downside? You can't type into it on the screen - it's a display method, and WYSIWYG print method. If you need to have the user type directly into the box, you're out of luck, unless you work-around (ex: enter name in simple text-box, and update the printPreview either as they go along, when the box loses focus, or when the press an update button.
I don't know your final needs, so I suggested a print/display oriented item rather than an editbox type item.
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"How do you find out if you're unwanted if everyone you try to ask tells you to go away?" - Balboos HaGadol
|
|
|
|
|
I get how to do some of the things now.. I just don't understand how to right align the words. I know how to left align the words but thats because they go from left to right.. How do I right align the words and make them go right to left? Does that make any sence?
e.Graphics.DrawString("Jacob Dixon", Tfont, Tbrush, rightalign, yPosition);
that sets the beginning of the text to where the right margin is.. well here is the rest for the right margins:
float rightalign = e.MarginBounds.Right;
Now how to I convert the drawstring to print right to left and not left to right like normal?
|
|
|
|
|
Ok I have figured that one out.. There is not much information out there about what I am looking for. Do you know where I can read up on some of this?
Now I'm looking for, I have a foreach statement for each of the children in the database. Now for each child I want it to print to a different page... What is is suppose to do is print out a end of year report for the parents of how much they paid that year.. now I have the settings and it prints the information, but how do I tell it to start printing on the next page for each child?
|
|
|
|
|
Multiple pages is (at first) tricky, although in reality it's simple.
You can do this by generating the page, but then, just before you leave the you set the graphics::HasMorePages member to true . Set it to false when the last page is printed. You'll then find your printPreview now contains all the pages.
and
since this is for printing, and not simply display, you may wish to use the printPreview dialog, which has all sorts of neat buttons and stuff built right in, making paging easy when checking your work.
Obvious reminder: when you want to center text, use arithmetic similar to that used to right justify, except divide the amount by two. A really important key idea, expanding upon your learning to right-justify, is to set up a page as much as possible by calculated values. If you do this correctly, you (or your user) can change fonts, and so on, and the page still works.
I learned to use the classes, once I got started, by browsing their members looking for interesting things and looking at how code was generated for me by the IDE.
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"How do you find out if you're unwanted if everyone you try to ask tells you to go away?" - Balboos HaGadol
|
|
|
|
|
Hi All,
One high level question from a .NET newbie I'm creating a C# WPF solution with two projects, one handling the presentation and one data layer creating a DataLayer .dll that the presentation references.
On start up I need to run something (a method?) that creates two datasets from XML files (that bit is all coded and working including XML validation) that are available app wide.
Whats the best way of doing this? is it something that should be done in the app code behind (that is currently in the presentation layer, is that even the right place?)
The datasets are going to used in some file recursion methods in the datalayer (which is also all coded and working) I just don't know the best place/method to initiate this loading of the lookups which I want to do only once at the app start up.
I was orginally building these in the main window code behind file but that means they are (as far as I can tell with me basic coding skills) unavailable to the data layer which needs them. Obviously added a reference to the presentation layer from the data layer is no go since that creates a reference loop.
I'm sure the answer is simple i'm just a bit stuck at the moment.
Thanks,
James.
|
|
|
|
|
The obvious way to do this, is to make the datasets properties inside your data layer. Then lazy initialise them. That means, you have this:
private DataSet _thedataset;
private DataSet TheDataSet
{
get
{
if (_thedataset == null)
{
// initialise
}
return _thedataset;
}
}
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
HAHA! ITS YOU AGAIN!
Hi fella,
Hope your well. You know I just cracked it about 30 seconds before you mail came through. Although what i Did is slightly different. Would love your feedback on what I did ...
Created a method in my BuildLoopUps class thus:
public static void CreateLookups()
{
DataSet dsInstruments = BuildLookups.LoadXmlFile(@"LookUpXML\instrument_lookup.xml");
DataSet dsExtensions = BuildLookups.LoadXmlFile(@"LookUpXML\ext_look_up.xml");
}
With these properties at the top:
public static DataSet dsInstruments;
public static DataSet dsExtensions;
Then in my FileInformation class I can:
foreach(string _fileExt in BuildLookups.dsExtensions)
{
}
What are the operational differences between these two ways of doing it? That is of course assuming that my way does in fact work!
Thanks,
James.
|
|
|
|
|
Ahh, i forgot to say that this:
BuildLookups.CreateLookups();
is the line directly above the InitializeComponent(); which is doing the actual kick off of the build process ...
|
|
|
|
|
oh man ... i'm back to your original advice about Dictionaries ... I can't "foreach" over a dataset can I ... DOH!
|
|
|
|
|
You can foreach over the tables in a dataset. You just need to specific foreach (datatable tbl in dataset.Tables).
The main difference is, doing it in a static constructor will do it when the app starts, my way won't do it until the first time you use it, and if it takes a while to build, that's the toss up. Have the app start faster, or have it quicker the first time you ask it to do something.
Lazy initialisation works best when it's a resource that takes time or space and isn't used every time the program runs, then you don't pay the price for it, until you need it.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Christian Graus wrote: Have the app start faster, or have it quicker the first time you ask it to do something.
Maybe we can slow down the speed of light and have both?
led mike
|
|
|
|
|
Gotcha! That does make a stack of sense ... it takes about 1-3 seconds foreach (geddit? har har) to import these two look ups and they are core to the functionality so are needed every time the app runs.
|
|
|
|
|
OK, so time is not that big a deal, but perhaps big enough that either way, your way makes more sense ( the static constructor )
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Gotcha.
Just a little quickie ... I get a warning on this line:
if (_fileExt == ThisRow[0])
Possible unintended reference comparison; to get a value comparison, cast the right hand side to type 'string'
I know that ThisRow[0] column contains a string, so it is safe to carry on without the .ToString()? As I understand it casting has an overhead that in this instance is not needed?
Thanks,
James.
|
|
|
|
|
I would obey the warning. A reference comparison means that you're checking if they are both the same string, not two strings with the same value. Big difference.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Not sure I follow, isn't this:
foreach (DataRow ThisRow in BuildLookups.dsExtensions.Tables["ext_look_up"].Rows)
{
if (_fileExt == ThisRow[0].ToString())
just saying foreach row in this table keep iterating until this string == (is the same as) the contents of ThisRow[0] (column 0)?
|
|
|
|
|
Well, you can cast it instead of calling tostring. Until you cast, it returns an object, so it compares the two objects to see if they are the same object. _fileExt and thisRow[0] may have the same value, but be different objects, different string instances.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
gotcha!
I know this is really cheecky but you've been so helpful in my endeavours to get my head into this I was wondering if I could ask a HUGE favour?
I don't feel confident in the general structure of what I'm doing in my app in terms of scope. I've just run into a scenario where I have a need for one of the lookups in the presentation layer but as I'm now building those in the data layer as you described they aren't available to the presentation layer.
feels like a huge 'gotcha' in a catch 22. Its a tiny app at the moment but would you be up for doing a brief code review if I emailed it to you?
Just some pointers on my 'coding myself into a corner' situation and wotnot. There are probably features of the language I've never encountered or heard about that would be the fix I'm looking for but I can't even ask questions about them as they are out of my field of vision.
Of course you can tell me to sling my hook!
James.
|
|
|
|
|
You can email me the code if you'd like, but I don't know how soon I'd have time to look at it. christian dot graus at gmail dot com
The best solution probably is to expose a method on the data layer that does the lookup you're after, but keep the data itself in the data layer.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Jammer wrote: I can't "foreach" over a dataset can I
No, and I'm still on .NET 2.0 but you can foreach over the rows in the tables in the DataSet.
led mike
|
|
|
|
|
hehe ... I just spotted my mistake in the code ... man, every time I reach for codeproject I say something daft and then after 30 seconds or so go ... "er ... ahhhhh" ...
|
|
|
|
|
Oh man I hate this error ...
"Object reference not set to an instance of an object." on this line:
foreach (DataRow ThisRow in BuildLookups.dsExtensions.Tables["ext_look_up"].Rows)
Whats the quickest way to actually debug issues like this. I always find myself getting a little confused by this one.
|
|
|
|