WPF Grid + Splitter + FlowDocumentScrollViewer - wpf

I have a WPF Grid with 4 rows:
Row 0 : Height = 1.0 (Grid Unit Type Star)
Row 1 - GridSplitter. Height GridLength.Auto
Row 2 - Height Fixed (About 20px)
Row 3 - FlowDocumentScrollViewer: Height GridLength.Auto
Row 1. 2, 3 are initially hidden (for this reasong height of row1 = 1.0). When clicking a button row 1, 2 and 3 are made visible.
I can't drag the splitter to make the flow document scroll viewer smaller.
If I drag the splitter to make it bigger, the Row 2 grows but the row 3 keeps with the same height.
¿How can I get the row 3 growing or shrunking properly? I post my code below:
void BuildComponents()
{
mainGrid= new Grid();
RowDefinition row0 = new RowDefinition();
RowDefinition splitterRow = new RowDefinition();
RowDefinicion fixedHeightRow = new RowDefinition();
RowDefinition scrolldocumentRow= new RowDefinition();
row0.Height = new GridLength(1.0, GridUnitType.Star);
splitterRow.Height = GridLength.Auto;
fixedHeightRow .Height = new GridLength(20, GridUnitType.Pixel);
scrolldocumentRow.Height = GridLength.Auto;
mainGrid.RowDefinitions.Add(row0);
mainGrid.RowDefinitions.Add(splitterRow);
mainGrid.RowDefinitions.Add(fixedHeightRow );
mainGrid.RowDefinitions.Add(scrolldocumentRow);
mainGrid.Children.Add(/*Grid Panel */);
mainGrid.Children.Add(Splitter);
mainGrid.Children.Add(/* Panel */);
mainGrid.Children.Add(/* Flow Document Scroll Viewer */);
Thank you

Related

WPF multipage printing for FixedDocument (Visual C# 2010)

I have a question about multipage FixedPage. I have a Grid created programmatically and the Grid exceeds one A4 page. Now I want to print the Grid in several FixedPage with print margin. But on my way, I create the Grid repeatedly and offset the LeftTop point in the fixedPage Arrange function. I meet a problem that I cannot set print margin in fixedPage, because I set the print margin to the fixedPage and then the first page will have print margin and the next pages will be blank.
How do print multipage of FixedDocument for a large grid want to print?
PrintDialog pd = new System.Windows.Controls.PrintDialog();
if (pd.ShowDialog() == false)
{
return;
}
var pageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
var document = new FixedDocument();
document.DocumentPaginator.PageSize = pageSize;
for (int nPage = 0; nPage < MaxPage; nPage++)
{
Grid tempGrid = LoadControlMotherInit();
tempGrid.Width = GridWidth;
tempGrid.Height = GridActualHeight;
Point leftTop = new Point();
leftTop.X = 10;
leftTop.Y = -nPage * pageSize.Height;
// Create FixedPage
var fixedPage = new FixedPage();
fixedPage.Width = pageSize.Width;
fixedPage.Height = pageSize.Height;
fixedPage.Margin = new Thickness(0, 0, 0, 96);
fixedPage.Children.Add((UIElement)tempGrid);
fixedPage.Measure(pageSize);
fixedPage.Arrange(new Rect(leftTop, pageSize));
fixedPage.UpdateLayout();
// Add page to document
var pageContent = new PageContent();
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
document.Pages.Add(pageContent);
}
pd.PrintDocument(document.DocumentPaginator, "My Document");
From looking at your example,
PrintDialog.PrintDocument method takes in a DocumentPaginator, which could come from a multitude of source.
that being said, you can inherit from DocumentPaginator and take control of everything from PageSize, PageCount to the actual DocumentPage being returned.
Imagine your DocumentPage as a sliding window over your UIElement; but instead of sliding your DocumentPage, you slide your UIElement using its RenderTransform.

Removing Last Row in WPF Grid

I want to remove the last row of a grid. I expect the last line to remove the row with the '2' in it. But whether I removeAt row 0 or 1, the 0th row is always removed. I suspect I am missing something subtle about rows vs grids. What am I doing wrong:
// Create row 0
RowDefinition row = new RowDefinition();
row.Height = GridLength.Auto;
myGrid.RowDefinitions.Add(row);
// Add someting to it
TextBox tb = new TextBox();
tb.Text = "1";
Grid.SetColumn(tb, 0);
Grid.SetRow(tb, 0);
myGrid.Children.Add(tb);
// create row 1
row = new RowDefinition();
row.Height = GridLength.Auto;
myGrid.RowDefinitions.Add(row);
// Add something to it
tb = new TextBox();
tb.Text = "2";
Grid.SetColumn(tb, 0);
Grid.SetRow(tb, 1);
myGrid.Children.Add(tb);
// Delete row 1 (second row 0-indexed) <<< only row 0 is deleted
myGrid.RowDefinitions.RemoveAt(1);
Note: I also tried:
myGrid.RowDefinitions.Remove(myGrid.RowDefinitions[1]);
same result. Thanks for any insight.
When you delete a row from a Grid it doesn't remove the children on that row, you will have to do that yourself. You could try iterating over the children of the Grid and remove any elements with a Row value equal to the row you want to remove...
var rowToDelete = 3;
foreach (var element in myGrid.Children)
{
if(Grid.GetRow(element) == rowToDelete)
{
myGrid.Children.Remove(element);
}
}

Silverlight, calculate shape Height & Width using persentage

I have a silverlight application that works but I now need to resize some items using a percentage instead of using fixed Height and Width.
My code snippit for this is:
private void drawCell(int row, int col, string label, Color fill)
{
Rectangle rect = new Rectangle();
rect.Height = cellSize;
rect.Width = cellSize;
rect.StrokeThickness = 2;
rect.Stroke = new SolidColorBrush(Colors.DarkGray);
rect.Fill = new SolidColorBrush(fill);
Grid.Children.Add(rect);
Canvas.SetLeft(rect, col * cellSize);
Canvas.SetTop(rect, row * cellSize);
Rectangle innertec = new Rectangle();
innertec.Height = cellSize - 30;
innertec.Width = cellSize - 10;
innertec.StrokeThickness = 1;
innertec.Stroke = new SolidColorBrush(Colors.Black);
innertec.Fill = new SolidColorBrush(fill);
innertec.Margin = new Thickness(5);
Grid.Children.Add(innertec);
Canvas.SetLeft(innertec, col * cellSize);
Canvas.SetTop(innertec, row * cellSize);
Border productLabelBorder = new Border();
TextBlock productLabel = new TextBlock();
productLabel.Height = cellSize - 60;
productLabel.Width = cellSize - 10;
productLabel.Margin = new Thickness(5, innertec.Height + 5, 0, 5);
productLabel.TextAlignment = TextAlignment.Center;
productLabel.TextWrapping = TextWrapping.NoWrap;
productLabel.TextTrimming = TextTrimming.WordEllipsis;
productLabel.Text = label;
ToolTipService.SetToolTip(productLabel, label);
productLabelBorder.Child = productLabel;
Grid.Children.Add(productLabelBorder);
Canvas.SetLeft(productLabelBorder, col * cellSize);
Canvas.SetTop(productLabelBorder, row * cellSize);
}
What I want the code to do is take the innertec and productLabel, and calculate the Height and Width by first looking at the cellSize (which is a variable set elsewhere) and then create these objects with a percentage of cellSize.
The reason for this is that cellSize changed size depending on a slider in the UI. The "cells" resize after calculating the area of the Canvas.
Is it possible to calculate these values as a percentage?
Thanks in advance for your help.
It looks like you are not using your Grid correctly! I can see you are adding items to the Grid, then trying to position them via the Canvas attached properties. You are mixing two different panel types!
With the Canvas, children are positions by their Top and Left coordinates
With the Grid children are located within cells as indicated by the Grid.Row and Grid.Column attached property.
You can use 'star' widths and heights to define the proportional width and height of rows / columns in order have grid cells which are some percentage of the overall grid. For example in markup, if you want to add a grid cell which is 50% of the overall grid size you can do the following:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions
<Button Grid.Column="1" Content="foo"/>
</Grid>
With the above, the Button will have a width which is 50% of the overall Grid width.

Programatically set the width of a DataColumn for use with a DataGrid

I assign a column programmatically to a DataTable like this:
myDataTable.Columns.Add(myDataColumn);
Is there a way to programmatically set the width / size of the column?
ColumnDefinition col1 = new ColumnDefinition();
col1.Width = GridLength.Auto;
ColumnDefinition col2 = new ColumnDefinition();
col2.Width = new GridLength(1,GridUnitType.Star);
grid.ColumnDefinitions.Add(col1);
grid.ColumnDefinitions.Add(col2);
top pieces will auto size columns, bottom piece you can customize size. look into this site for more detail -- http://www.wpftutorial.net/GridLayout.html
This resizes N-1 columns to "Auto" and column N to "Fill"
foreach (var column in dataGrid.Columns)
column.Width = DataGridLength.Auto;
dataGrid.Columns.Last().Width = DataGridLength.SizeToCells;

WPF - Text box that grows vertically to accommodate all text

The problem: I am not getting a textbox setting that will have a horizontally wordwrap and vertically auto grow functionality. I wish to do that by writing a code. I have written following code that creates a text box at mouse dblclick with wordwrap:
TextBox text2 = new TextBox();
text2.Width = 500;
text2.Visibility = Visibility.Visible;
text2.Focus();
text2.Height = 30;
text2.HorizontalAlignment = HorizontalAlignment.Left;
text2.VerticalAlignment = VerticalAlignment.Top;
Point p = e.GetPosition(LayoutRoot);
text2.Margin = new Thickness(p.X, p.Y, 0, 0);
LayoutRoot.Children.Add(text2);
But, textbox does not grow vertically.
Can somebody suggest me a code in C# to do exactly what I desire?
try using this
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
grid.RowDefinitions.Add(new RowDefinition());
TextBox textBox = new TextBox() { Width = 100, TextWrapping = TextWrapping.Wrap };
textBox.SetValue(Grid.RowProperty, 0);
grid.Children.Add(textBox);
window.Content = grid;
where window is the Name assigned to Window(root).
One way to accomplish the growth you're looking for is to use a string measuring mechanism which you would run any time the text in your text box changes. Simply measure and resize your text box accordingly with any change to the contents.
Have you tried this?
text2.Height = double.NaN; // or don't set the property, but some custom styles might give a default value ..
text2.TextWrapping = TextWrapping.Wrap;
text2.MinHeight = 30; // or not if you want the styles default
instead of
text2.Height = 30;
not setting it or using double.NaN is the same as using 'Auto' in xaml.

Resources