Problem creating Silverlight Grid columns programmatically on WP7 - silverlight

I'm trying to create a user control which will allow me to pass in a list of column definitions and which will create a grid for me.
So far nothing is displaying. Here is the code:
List<GridColumn> colList = new List<GridColumn>();
GridColumn col1 = new GridColumn(200, "AAA");
colList.Add(col1);
GridColumn col2 = new GridColumn(200, "BBB");
colList.Add(col2);
BuildColumns(MainGrid, colList)
private void BuildColumns(Grid mainGrid, List<GridColumn> gridColumnList)
{
// create grid columns
foreach (GridColumn gridColumn in gridColumnList)
{
GridLength len = new GridLength(gridColumn.ColumnWidth);
ColumnDefinition col = new ColumnDefinition {Width = len};
mainGrid.ColumnDefinitions.Add(col);
}
// add 2 rows
GridLength height = new GridLength(100);
RowDefinition rowDef1 = new RowDefinition {Height = height};
mainGrid.RowDefinitions.Add(rowDef1);
RowDefinition rowDef2 = new RowDefinition {Height = height};
mainGrid.RowDefinitions.Add(rowDef2);
// add text blocks to cells
int colNum = -1;
foreach (GridColumn gridColumn in gridColumnList)
{
colNum++;
TextBlock textBlock = new TextBlock();
textBlock.Text = gridColumn.ColumnName;
Grid.SetRow(textBlock, 0);
Grid.SetColumn(textBlock, colNum);
}
}
I have tried increasing the row/column size and refreshing the grid.
This is the same as this earlier question but the answer did not fix my problem.
This is what it looks like on the phone

The problem is that you aren't actually adding the TextBlock elements into the visual tree. You need to add them to the Children collection on the mainGrid Grid element supplied to the BuildColumns method.
private void BuildColumns(Grid mainGrid, List gridColumnList)
{
// create grid columns
foreach (GridColumn gridColumn in gridColumnList)
{
GridLength len = new GridLength(gridColumn.ColumnWidth);
ColumnDefinition col = new ColumnDefinition { Width = len };
mainGrid.ColumnDefinitions.Add(col);
}
// add 2 rows
GridLength height = new GridLength(100);
RowDefinition rowDef1 = new RowDefinition {Height = height};
mainGrid.RowDefinitions.Add(rowDef1);
RowDefinition rowDef2 = new RowDefinition {Height = height};
mainGrid.RowDefinitions.Add(rowDef2);
// add text blocks to cells
int colNum = -1;
foreach (GridColumn gridColumn in gridColumnList)
{
colNum++;
TextBlock textBlock = new TextBlock();
textBlock.Text = gridColumn.ColumnName;
Grid.SetRow(textBlock, 0);
Grid.SetColumn(textBlock, colNum);
mainGrid.Children.Add(textBlock); // This line makes all the difference.
}
}

Related

Is there two way binding between table.defaultview and listview.itemsource?

I have a stackpanel with multiple usercontrols being created in code behind. When I genereate these usercontrols there are tables being filled with data in the app, then I click a button and in the code behind I want to fetch the data filled in the tables, but when I step through the code it doesn't seem like the tables are being refreshed/updated/filled with the new data. Do I need to set something to two way binding or updating something?
Here is my code.
private void TestGridValues_OnClick(object sender, RoutedEventArgs e)
{
StackPanel stackPanel = this.TestGrids;
foreach (UserControl child in stackPanel.Children)
{
Grid content = child.Content as Grid;
ListView view = content.Children[0] as ListView;
ItemCollection itemCollection = view.Items;
DataRowView dataRowView = itemCollection.CurrentItem as DataRowView;
DataTable dataTable = dataRowView.DataView.Table;
}
}
private void MakeGridviewColumns(DataTable table)
{
this.ModelerListView.ItemsSource = table.DefaultView;
GridView gv = new GridView();
this.ModelerListView.View = gv;
// add the date column to gridview
GridViewColumn dateColumn = new GridViewColumn();
dateColumn.Header = "Date";
gv.Columns.Add(dateColumn);
dateColumn.DisplayMemberBinding = new Binding("Date");
foreach (DataColumn dataColumn in table.Columns)
{
if (dataColumn.ColumnName == "Date")
continue;
GridViewColumn gvc = new GridViewColumn();
gvc.Header = dataColumn.ColumnName;
DataTemplate dt = new DataTemplate();
FrameworkElementFactory txtBoxElement = new FrameworkElementFactory(typeof(TextBox));
Binding bind = new Binding();
bind.Path = new PropertyPath("Text");
bind.Mode = BindingMode.TwoWay;
txtBoxElement.SetBinding(TextBox.TextProperty, bind);
txtBoxElement.SetValue(TextBox.TextProperty, "test");
dt.VisualTree = txtBoxElement;
gvc.CellTemplate = dt;
gv.Columns.Add(gvc);
}
}

Print Grid which generated dynamically in 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

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.

WPF Binding a Dynamically Added Control

I am adding a to the "Company" RibbonApplicationMenuItem in my RibbonWindow with the following code:
var reset = DataContext as ICompanies;
if (reset != null)
{
// ToDo: Create interface to populate the mymenutems
var mymenuitems = new List<string>();
foreach (var item in mymenuitems)
{
var newbutton = new Button { Margin = new Thickness(2), Content = item };
MenuItem_Company.Items.Add(newbutton);
}
}
My XAML looks like this:
<ribbon:RibbonApplicationMenu ToolTipTitle="Application Menu">
<ribbon:RibbonApplicationMenuItem
Header="Company"
x:Name="MenuItem_Company"
ImageSource="Images\LargeIcon.png">
</ribbon:RibbonApplicationMenuItem>
</ribbon:RibbonApplicationMenu>
How do I bind my new button in code when I add it to the MenuItem_Company? I need it to bind to a property in my datacontext.
Thanks,
Eroc
var newbutton = new Button { Margin = new Thickness(2), Content = item };
Binding b = new Binding();
b.Source = reset;
b.Path = new PropertyPath("SomePropertyOnDataContext");
newButton.SetBinding(Button.IsEnabledProperty, b);
Varying assumptions in the code...but it should give you an idea where to start...

WPF Table Column Sizes

I'm rendering a Table in a WPF FlowDocument using code-behind. But, I've been unable to find an example that shows how to make the table use only the space needed based on content. Instead the table takes up all available width, which I don't want, nor do I want to have to specify a exact pixel sizes.
I'm clearly missing something simple, anyone see it?
var fd = new FlowDocument();
Table t = new Table();
t.BorderBrush = Brushes.Black;
t.BorderThickness = new Thickness(2);
// I thought this would do what I wanted...
t.Columns.Add(new TableColumn() { Width = GridLength.Auto });
t.Columns.Add(new TableCOlumn() { Width = GridLength.Auto });
TableRowGroup trg = new TableRowGroup();
TableRow currentRow = new TableRow();
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("ABC"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("XYZ"))));
trg.Rows.Add(currentRow);
currentRow = new TableRow();
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("123"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("789"))));
trg.Rows.Add(currentRow);
t.RowGroups.Add(trg);
fd.Blocks.Add(t);
I do not think this is possible... the only hacky workaround is to use the BlockUIContainer and a real grid!
var fd = new FlowDocument();
Grid g = new Grid();
g.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
g.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
g.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
g.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
var t1 = new TextBlock() { Text = "ABC", Margin = new Thickness(5,3,5,3) };
t1.SetValue(Grid.ColumnProperty, 0);
t1.SetValue(Grid.RowProperty, 0);
g.Children.Add(t1);
var t2 = new TextBlock() { Text = "XYZ", Margin = new Thickness(5, 3, 5, 3) };
t2.SetValue(Grid.ColumnProperty, 1);
t2.SetValue(Grid.RowProperty, 0);
g.Children.Add(t2);
var t3 = new TextBlock() { Text = "123", Margin = new Thickness(5, 3, 5, 3) };
t3.SetValue(Grid.ColumnProperty, 0);
t3.SetValue(Grid.RowProperty, 1);
g.Children.Add(t3);
var t4 = new TextBlock() { Text = "789", Margin = new Thickness(5, 3, 5, 3) };
t4.SetValue(Grid.ColumnProperty, 1);
t4.SetValue(Grid.RowProperty, 1);
g.Children.Add(t4);
fd.Blocks.Add(new BlockUIContainer(g));
try TableCell.ColoumnSpan and TableCell.RowSpan
I know the question was asked 9 years ago, but I found out an alternate way to do this without using a BlockUIContainer which quite frankly is a pain when serializing the FlowDocument or when the user is just editing the document in a RichTextBox.
Add a PreviewMouseMove and PreviewMouseDown handler to every single table cells. In PreviewMouseMove change the cursor to SizeWE whenever adjacent to the cell border. In PreviewMouseDown capture the mouse using the RichTextBox as the source.
Add a PreviewMouseMove and PreviewMouseUp handler to the RichTextBox. In PreviewMouseMove resize the table column based on the calculated horizontal delta movement. In PreviewMouseUp release the mouse.
The tricky part is to figure where the cell borders are because there's no way out of the box to just get the cell position or width. So you have to approximate where they are by doing the sum of the PagePadding, Table Padding and column widths.

Resources