Print Grid which generated dynamically in wpf - wpf

i want to print a grid which is generated dynamically.
Means, in the click event of the Print Button, i m generating a grid and then i want to print that grid.
here is my code,
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
PrintDialog Objprint = new System.Windows.Controls.PrintDialog();
if (Objprint.ShowDialog() == true)
{
System.Printing.PrintCapabilities capabilities = Objprint.PrintQueue.GetPrintCapabilities(Objprint.PrintTicket);
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.ActualWidth, capabilities.PageImageableArea.ExtentHeight / this.ActualHeight);
#region "Make a grid For Printing"
Grid objgrid = new Grid();
objgrid.Name = "GridForPrinting";
objgrid.Width = 1000;
objgrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
objgrid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
objgrid.RowDefinitions.Add(new RowDefinition());
TextBlock objtext = new TextBlock();
objtext.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
objtext.VerticalAlignment = System.Windows.VerticalAlignment.Center;
objtext.Text = "SUPERIOR COURT OF CALIF COUNTY OF SAN BERNARDINO";
Grid.SetRow(objtext, 0);
objgrid.Children.Add(objtext);
#endregion
Objprint.PrintVisual(objgrid, "Case Summary");
}
}
this code give me blank page to print.
how can i do that?

here i get answer,
from the below code i get what i want to do...
void PrintOnClick(object sender, RoutedEventArgs args)
{
PrintDialog dlg = new PrintDialog();
if ((bool)dlg.ShowDialog().GetValueOrDefault())
{
// Create Grid panel.
Grid grid = new Grid();
// Define 5 auto-sized rows and columns.
for (int i = 0; i < 5; i++)
{
ColumnDefinition coldef = new ColumnDefinition();
coldef.Width = GridLength.Auto;
grid.ColumnDefinitions.Add(coldef);
RowDefinition rowdef = new RowDefinition();
rowdef.Height = GridLength.Auto;
grid.RowDefinitions.Add(rowdef);
}
// Give the Grid a gradient brush.
grid.Background =
new LinearGradientBrush(Colors.Black, Colors.White,
new Point(0, 0), new Point(1, 1));
// Every program needs some randomness.
Random rand = new Random();
// Fill the Grid with 25 buttons.
for (int i = 0; i < 25; i++)
{
Button btn = new Button();
btn.FontSize = 12 + rand.Next(8);
btn.Content = "Button No. " + (i + 1);
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.VerticalAlignment = VerticalAlignment.Center;
btn.Margin = new Thickness(6);
grid.Children.Add(btn);
Grid.SetRow(btn, i % 5);
Grid.SetColumn(btn, i / 5);
}
// Size the Grid.
grid.Measure(new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
Size sizeGrid = grid.DesiredSize;
// Determine point for centering Grid on page.
Point ptGrid =
new Point((dlg.PrintableAreaWidth - sizeGrid.Width) / 2,
(dlg.PrintableAreaHeight - sizeGrid.Height) / 2);
// Layout pass.
grid.Arrange(new Rect(ptGrid, sizeGrid));
// Now print it.
dlg.PrintVisual(grid, Title);
}
}

The PrintVisual print a Visual object. That means, by using the PrintVisual method, we can print any control, container, Window or user control that is in the visualtree.You cannot print a control that is not in the visualtree

Related

WPF - pass data from page A to page B

So I want to pass data when I clicked an Canvas. So I have this code;
Canvas event_canvas = new Canvas();
event_canvas.Background = new SolidColorBrush(Color.FromRgb(66, 70, 77));
event_canvas.Width = 250;
event_canvas.Height = 60;
event_canvas.Margin = new Thickness(40, 0, 0, 0);
event_canvas.HorizontalAlignment = HorizontalAlignment.Left;
event_canvas.VerticalAlignment = VerticalAlignment.Top;
event_canvas.Cursor = Cursors.Hand;
#endregion
#region Grid (event_grid)
Grid event_grid = new Grid();
event_grid.Width = 250;
event_grid.Height = 60;
#endregion
#region TextBlock (event_text)
TextBlock event_text = new TextBlock();
event_text.VerticalAlignment = VerticalAlignment.Center;
event_text.HorizontalAlignment = HorizontalAlignment.Center;
event_text.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
event_text.Text = e.name;
#endregion
event_grid.Children.Add(event_text); // Add the textblock to the grid
event_canvas.Children.Add(event_grid); // Add the grid to the canvas
grid_events.Children.Add(event_canvas); // Add the canvas to the main grid.
// Click event registration
event_canvas.MouseLeftButtonDown += Event_canvas_MouseLeftButtonDown;
And then in the trigger;
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Page pg = new EventDetailPage();
// Replaces all the content!!!!!
this.Content = pg;
//throw new NotImplementedException();
}
I tried to add this;
var param = ((TextBlock)sender).Text;
Page pg = new EventDetailPage(param);
But that code doesn't work, it throws an error that I can't get a value.
How can I fix this issue?
Cast the sender argument to Canvas and then access the Grid through the Canvas' Children collecton and the TextBlock through the Grid's Children collecton:
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Canvas canvas = (Canvas)sender;
Grid event_grid = canvas.Children[0] as Grid;
TextBlock event_text = event_grid.Children[0] as TextBlock;
string text = event_text.Text;
...
}

GridSplitter Not present

I use this in code behind to test how to add a grid splitter programmatically. (I know, don't use code behind - But this is one of those rare cases I need to. (I think))
public partial class ContainerView : Window, IContainerView
{
[ImportingConstructor]
public ContainerView()
{
InitializeComponent();
SetUp();
}
public void SetUp()
{
_grid = new Grid();
//Single column/single row
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
var button1 = new Button();
button1.Content = "Btn 1";
button1.Margin = new Thickness(5);
Grid.SetRow(button1, 0);
Grid.SetColumn(button1, 0);
var button2 = new Button();
button2.Content = "Btn 2";
button2.Margin = new Thickness(5);
Grid.SetRow(button2, 1);
Grid.SetColumn(button2, 2);
_grid.Children.Add(button1);
_grid.Children.Add(button2);
var splitterV = new GridSplitter();
Grid.SetRowSpan(splitterV, _grid.RowDefinitions.Count);
splitterV.VerticalAlignment = VerticalAlignment.Stretch;
splitterV.HorizontalAlignment = HorizontalAlignment.Right;
splitterV.ShowsPreview = true;
splitterV.Background = Brushes.Black;
Width = 5;
_grid.Children.Add(splitterV);
Grid.SetColumn(splitterV, 1);
Content = _grid;
}
I can see the two buttons, but the middle column is empty. The GridSplitter is not shown. What am I doing wrong?
You are absolutely correct but you are setting Window's width instead of GridSpitter's width & also you have to give it's ResizeBehaviour.
Instead of this :
Width = 5;
Set GridSpitter's Width & It's ResizeBehavior as :
splitterV.ResizeBehavior = GridResizeBehavior.PreviousAndNext;
splitterV.Width = 5;

Radiobuttons are invisible inside of Array of Panels

In the Form constructor I generate an array of panels (pnl_ in the code below), that include radiobuttons.
When I visualize the Form, only panels are visible, NOT radiobuttons inside.
Curiously, everything is OK, when I generate only one panel (pnl in the code below).
public partial class Radiobuttons_on_Panel : Form
{
private Panel pnl = new Panel();
private RadioButton rbtn1 = new RadioButton();
private RadioButton rbtn2 = new RadioButton();
private Panel[] pnl_ = new Panel[7];
private RadioButton[] rbtn1_ = new RadioButton[7];
private RadioButton[] rbtn2_ = new RadioButton[7];
public Radiobuttons_on_Panel()
{
InitializeComponent();
pnl.Location = new Point(10, 10);
pnl.Size = new Size(100, 100);
pnl.BorderStyle = BorderStyle.FixedSingle;
rbtn1.Location = pnl.Location;
rbtn1.Text = "AAA";
rbtn2.Location = new Point(pnl.Location.X, pnl.Location.Y + rbtn1.Height);
rbtn2.Text = "BBB";
pnl.Controls.Add(rbtn1);
pnl.Controls.Add(rbtn2);
this.Controls.Add(pnl);
for (int i = 0; i < pnl_.Length; i++)
{
pnl_[i] = new Panel();
pnl_[i].BorderStyle = BorderStyle.FixedSingle;
pnl_[i].Size = new Size(100, 100);
pnl_[i].Location = new Point(10 + i * 110, 200);
rbtn1_[i] = new RadioButton();
rbtn1_[i].Location = pnl_[i].Location;
rbtn1_[i].Text = "AAA";
rbtn2_[i] = new RadioButton();
rbtn2_[i].Location = new Point(pnl_[i].Location.X, pnl_[i].Location.Y + rbtn1_[i].Height);
rbtn2_[i].Text = "BBB";
pnl_[i].Controls.Add(rbtn1_[i]);
pnl_[i].Controls.Add(rbtn2_[i]);
this.Controls.Add(pnl_[i]);
}
}
}
Where is the problem?
Your problem with this is that your calculation of location is wrong. The location of the radio buttons are relative to their container - in this case, the panels. If you just set your locations to
rbtn1_[i] = new RadioButton();
rbtn1_[i].Location = new Point(10, 10);
rbtn1_[i].Text = "AAA";
rbtn2_[i] = new RadioButton();
rbtn2_[i].Location = new Point(rbtn1_[i].Location.X, rbtn1_[i].Location.Y + rbtn1_[i].Height);
rbtn2_[i].Text = "BBB";
the buttons will lay out like you want them to.
Thing work out in your first one because your radio button locations values are small enough to be visible in the panel. For those others, well, they are outside the bounds of their parent panels.
The long and short of it is that the Location property is always relative to the container, whether that is a Panel or a Form - the Location values for your panels are relative to the Form but the the Location values for your radio buttons are relative to whatever panel they are in.
MSDN Reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.location.aspx

dynamic button event in xml parsing

i create a dynamic button(xmlparsingbuildbutton) during a buttonclick(xmlparsingbutton) event.
I did a xml parsing...once each xml target is parsed, they will create an individual checkbox. What i need is this: Create a dynamic button event(xmlparsingbuildbutton). During this dynamic button event, for every checkbox that is checked, they will append a text file by writing new lines into the text file. This gets confusing to me because right now i have a foreachloop embedded in the xmlparsingbutton event that creates all these checkboxes.
Right now, I've coded it in such a way that whenever i check the checkboxes, my append of file event will not fire therefore I created this "xmlparsingbuildbutton" to help fire the event.From my understanding, usually i would hard code buttonclickevent, however in this case the target value always change in the foreach loop and therefore it is not right to just merely hardcode the buttonclickevent.
So my question is how do i have this button event to be inside the foreach loop of the xmlparsing event button? Please clarify my doubts. Many thanks!
Here is my code:
private void xmlparsingButton_Click(object sender, RoutedEventArgs e)
{
XDocument xmlDoc = XDocument.Load(#"C:\Build.xml");
var abc = from target in xmlDoc.Descendants("target")
select (string)target.Attribute("if");
ColumnDefinition gridCol1 = new ColumnDefinition();
gridCol1.Width = new GridLength(300);
ColumnDefinition gridCol2 = new ColumnDefinition();
gridCol2.Width = new GridLength(300);
ColumnDefinition gridCol3 = new ColumnDefinition();
gridCol3.Width = new GridLength(300);
ColumnDefinition gridCol4 = new ColumnDefinition();
gridCol4.Width = new GridLength(300);
tab4grid.ColumnDefinitions.Add(gridCol1);
tab4grid.ColumnDefinitions.Add(gridCol2);
tab4grid.ColumnDefinitions.Add(gridCol3);
tab4grid.ColumnDefinitions.Add(gridCol4);
RowDefinition gridRow1 = new RowDefinition();
gridRow1.Height = new GridLength(50);
RowDefinition gridRow2 = new RowDefinition();
gridRow2.Height = new GridLength(50);
RowDefinition gridRow3 = new RowDefinition();
gridRow3.Height = new GridLength(50);
RowDefinition gridRow4 = new RowDefinition();
gridRow4.Height = new GridLength(50);
RowDefinition gridRow5 = new RowDefinition();
gridRow5.Height = new GridLength(50);
RowDefinition gridRow6 = new RowDefinition();
gridRow6.Height = new GridLength(50);
RowDefinition gridRow7 = new RowDefinition();
gridRow7.Height = new GridLength(50);
RowDefinition gridRow8 = new RowDefinition();
gridRow8.Height = new GridLength(50);
RowDefinition gridRow9 = new RowDefinition();
gridRow9.Height = new GridLength(50);
RowDefinition gridRow10 = new RowDefinition();
gridRow10.Height = new GridLength(50);
RowDefinition gridRow11 = new RowDefinition();
gridRow11.Height = new GridLength(50);
RowDefinition gridRow12 = new RowDefinition();
gridRow12.Height = new GridLength(50);
tab4grid.RowDefinitions.Add(gridRow1);
tab4grid.RowDefinitions.Add(gridRow2);
tab4grid.RowDefinitions.Add(gridRow3);
tab4grid.RowDefinitions.Add(gridRow4);
tab4grid.RowDefinitions.Add(gridRow5);
tab4grid.RowDefinitions.Add(gridRow6);
tab4grid.RowDefinitions.Add(gridRow7);
tab4grid.RowDefinitions.Add(gridRow8);
tab4grid.RowDefinitions.Add(gridRow9);
tab4grid.RowDefinitions.Add(gridRow10);
tab4grid.RowDefinitions.Add(gridRow11);
tab4grid.RowDefinitions.Add(gridRow12);
int i = 0;
int j = 1;
System.Windows.Controls.Button XmlparsingbuildButton = new System.Windows.Controls.Button();
Grid.SetColumn(XmlparsingbuildButton, 4);
Grid.SetRow(XmlparsingbuildButton, 12);
XmlparsingbuildButton.Height = 23;
XmlparsingbuildButton.Width = 51;
XmlparsingbuildButton.Content = "Build";
tab4grid.Children.Add(XmlparsingbuildButton);
foreach(string target in abc)
{
if (target != null && !Dictionarycheck.ContainsKey(target))
{
System.Windows.Controls.CheckBox chk = new System.Windows.Controls.CheckBox();
chk.Name = target+"CheckBox";
chk.Content = target;
Grid.SetColumn(chk, i); //sets column
Grid.SetRow(chk, j); //sets row
tab4grid.Children.Add(chk); //adds the control
Tabitem5.Visibility = Visibility.Visible;
i++;
if (i == 4)
{
j++;
i = 0;
}
if (chk.IsChecked == true)
{
using (var writer = File.AppendText(#"c:\testing.txt"))
{
writer.WriteLine(target);
}
}
}
}
Tabitem5.Visibility = Visibility.Visible;
Tabcontrol1.SelectedIndex = 4;
}
I have to admit, I have problems understanding your problem. If I get it right, you're trying to do the following:
Parse a Xml document ("C:\Build.xml") with (roughly) this format:
targets>
target if="aaa" />
target if="bbb" />
/targets>
Create a CheckBox for each target tag with if- attribute set
Check the CheckBox containing the string you want to use
Click a button to append the checked strings to a text file ("c:\testing.txt")
If this is correct, then I think your solution won't do that. I not sure if I can understand what you are trying to do in your code. The way you set up the comboboxes they will never be checked the time you use your writer.
How about this:
Use a StackPanel (stackPanel1) instead of a grid. That way you don't have to create all the row definitions. (Ok, I have to admit, I don't know what all these columns are for)
Create a simple logic for a button to append the checked ComboBoxes to the file
code:
private void xmlparsingButton_Click(object sender, RoutedEventArgs e)
{
stackPanel1.Children.Clear();
XDocument xmlDoc = XDocument.Load(#"C:\Build.xml");
var abc = from target in xmlDoc.Descendants("target")
select (string) target.Attribute("if");
foreach (string target in abc)
{
if (target != null)
{
System.Windows.Controls.CheckBox chk = new System.Windows.Controls.CheckBox();
chk.Name = target + "CheckBox";
chk.Content = target;
chk.Tag = target;
stackPanel1.Children.Add(chk);
}
}
}
private void btnAppendToTextFile_Click(object sender, RoutedEventArgs e)
{
using (var writer = File.AppendText(#"c:\testing.txt"))
{
foreach (var child in stackPanel1.Children)
{
if ((child is CheckBox) && ((CheckBox) child).IsChecked.Value)
{
writer.WriteLine(((CheckBox)child).Tag);
}
}
}
}
I hope this helps you with your problem.

C# Winform: How to set the Base Color of a TabControl (not the tabpage)

It seems like a simple question but how do I set the bacground color of the 'tab control', it seems to be derived from the standard window theme color. Is it Possible to create a black tab control with white text written on the tabs themselves (not the tab page)?
Help, I,m a little familiar with custom controls extending existing controls but I don't know what properties (if they exist) to set.
http://dotnetrix.co.uk/tabcontrol.htm
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
TabPage CurrentTab = tabControl1.TabPages[e.Index];
Rectangle ItemRect = tabControl1.GetTabRect(e.Index);
SolidBrush FillBrush = new SolidBrush(Color.Red);
SolidBrush TextBrush = new SolidBrush(Color.White);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
//If we are currently painting the Selected TabItem we'll
//change the brush colors and inflate the rectangle.
if (System.Convert.ToBoolean(e.State & DrawItemState.Selected))
{
FillBrush.Color = Color.White;
TextBrush.Color = Color.Red;
ItemRect.Inflate(2, 2);
}
//Set up rotation for left and right aligned tabs
if (tabControl1.Alignment == TabAlignment.Left || tabControl1.Alignment == TabAlignment.Right)
{
float RotateAngle = 90;
if (tabControl1.Alignment == TabAlignment.Left)
RotateAngle = 270;
PointF cp = new PointF(ItemRect.Left + (ItemRect.Width / 2), ItemRect.Top + (ItemRect.Height / 2));
e.Graphics.TranslateTransform(cp.X, cp.Y);
e.Graphics.RotateTransform(RotateAngle);
ItemRect = new Rectangle(-(ItemRect.Height / 2), -(ItemRect.Width / 2), ItemRect.Height, ItemRect.Width);
}
//Next we'll paint the TabItem with our Fill Brush
e.Graphics.FillRectangle(FillBrush, ItemRect);
//Now draw the text.
e.Graphics.DrawString(CurrentTab.Text, e.Font, TextBrush, (RectangleF)ItemRect, sf);
//Reset any Graphics rotation
e.Graphics.ResetTransform();
//Finally, we should Dispose of our brushes.
FillBrush.Dispose();
TextBrush.Dispose();
}
I use something like this in mu TabControl derived class (and it will do gradients too):
protected override void OnDrawItem(DrawItemEventArgs e)
{
// fill in the whole rect
using (SolidBrush br = new SolidBrush(Theme.FormBackColor))
{
e.Graphics.FillRectangle(br, ClientRectangle);
}
// draw the tabs
for (int i = 0; i < TabPages.Count; ++i)
{
TabPage tab = TabPages[i];
// Get the text area of the current tab
RectangleF tabTextArea = (RectangleF)GetTabRect(i);
// determine how to draw the tab based on which type of tab it is
Color tabTopBackColor = GetTopBackColor();
Color tabBottomBackColor = GetBottomBackColor();
Color tabTextColor = GetTextColor();
// draw the background
using (LinearGradientBrush br = new LinearGradientBrush(tabTextArea, tabTopBackColor, tabBottomBackColor, LinearGradientMode.Vertical))
{
e.Graphics.FillRectangle(br, tabTextArea);
}
// draw the tab header text
using (SolidBrush brush = new SolidBrush(tabTextColor))
{
e.Graphics.DrawString(tab.Text, Font, brush, CreateTabHeaderTextRect(tabTextArea));
}
}
}
private RectangleF CreateTabHeaderTextRect(RectangleF tabTextArea)
{
tabTextArea.X += 3;
tabTextArea.Y += 1;
tabTextArea.Height -= 1;
return tabTextArea;
}

Resources