Click event for programatically generated XAML buttons - c#

I'm programatically generating a table where Text2 the columns are a button:
for (int i = 0; i < workPackages.Length; i++)
{
//Define new Row to add
RowDef = new RowDefinition();
RowDef.Height = new GridLength(60);
//Add row definition to Grid
WorkPackageResults.RowDefinitions.Add(RowDef);
//Define the control that will be added to new row
Text1 = new TextBlock();
Text1.Text = workPackages[i].EWPStatus;
Text1.Width = 100;
Text1.TextAlignment = TextAlignment.Center;
Text2 = new Button();
Text2.Content = workPackages[i].EWPCode;
Text2.Width = 300;
Text3 = new TextBlock();
Text3.Text = workPackages[i].Description;
Text3.Width = 500;
Text3.TextAlignment = TextAlignment.Center;
Text4 = new TextBlock();
Text4.Text = workPackages[i].ForeBadge;
Text4.Width = 100;
Text4.TextAlignment = TextAlignment.Center;
//create stackpanel and define which row to add the stackpanel to
StackP = new StackPanel();
StackP.SetValue(Grid.RowProperty, i);
StackP.Orientation = Orientation.Horizontal;
StackP.Margin = new Thickness(50, 0, 0, 0);
//add your control to the stackpanel
StackP.Children.Add(Text1);
StackP.Children.Add(Text2);
StackP.Children.Add(Text3);
StackP.Children.Add(Text4);
//add the stackpanel to the grid
WorkPackageResults.Children.Add(StackP);
}
How do I programatically add a click event? And when that click event is executed how do I know which button it came from?

Add an event handler to Text2.Click that will pass the sender as a parameter, that's how you know which one was clicked.

Related

How to display my images in a 4 by 4 grid using c#?

Currently my images just go down vertically, I want 4 images to display horizontally in each row, I've tried few suggestions on here but can't seem to get it working to work, its quite confusing to me as a beginner.
foreach (MyWCF.dogs c in lc)
{
RowDefinition row = new RowDefinition();
row.Height = new GridLength(1.0, GridUnitType.Auto);
g.RowDefinitions.Add(row);
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
BitmapImage image = new BitmapImage();
Image i1 = new Image();
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0)))
{
writer.WriteBytes((byte[])p.images);
writer.StoreAsync().GetResults();
}
//var image = new BitmapImage();
image.SetSource(ms);
}
i1.Source = image;
i1.Height = 100;
sp.Children.Add(i1);
Grid.SetRow(sp, gridRef);
g.Children.Add(sp);
gridRef++;
}
(Trying again with the Microsoft code explicitly included. I presume its OK to point to S.O. answers instead of copying an pasting the entirety of the S.O. answer here )
Perhaps the tutorial Grid Class : "Defines a flexible grid area that consists of columns and rows." will help. Then, this S.O. question Adding Image to Grid C# shows how to add images to a WPF grid.
Here is the material from the Grid Class post:
The following C# example demonstrates how to create a grid. In this case, the grid defines three ColumnDefinition elements and four RowDefinition elements that host child content.
// Create the application's main window
mainWindow = new Window();
mainWindow.Title = "Grid Sample";
// Create the Grid
Grid myGrid = new Grid();
myGrid.Width = 250;
myGrid.Height = 100;
myGrid.HorizontalAlignment = HorizontalAlignment.Left;
myGrid.VerticalAlignment = VerticalAlignment.Top;
myGrid.ShowGridLines = true;
// Define the Columns
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(colDef1);
myGrid.ColumnDefinitions.Add(colDef2);
myGrid.ColumnDefinitions.Add(colDef3);
// Define the Rows
RowDefinition rowDef1 = new RowDefinition();
RowDefinition rowDef2 = new RowDefinition();
RowDefinition rowDef3 = new RowDefinition();
RowDefinition rowDef4 = new RowDefinition();
myGrid.RowDefinitions.Add(rowDef1);
myGrid.RowDefinitions.Add(rowDef2);
myGrid.RowDefinitions.Add(rowDef3);
myGrid.RowDefinitions.Add(rowDef4);
// Add the first text cell to the Grid
TextBlock txt1 = new TextBlock();
txt1.Text = "2005 Products Shipped";
txt1.FontSize = 20;
txt1.FontWeight = FontWeights.Bold;
Grid.SetColumnSpan(txt1, 3);
Grid.SetRow(txt1, 0);
// Add the second text cell to the Grid
TextBlock txt2 = new TextBlock();
txt2.Text = "Quarter 1";
txt2.FontSize = 12;
txt2.FontWeight = FontWeights.Bold;
Grid.SetRow(txt2, 1);
Grid.SetColumn(txt2, 0);
// Add the third text cell to the Grid
TextBlock txt3 = new TextBlock();
txt3.Text = "Quarter 2";
txt3.FontSize = 12;
txt3.FontWeight = FontWeights.Bold;
Grid.SetRow(txt3, 1);
Grid.SetColumn(txt3, 1);
// Add the fourth text cell to the Grid
TextBlock txt4 = new TextBlock();
txt4.Text = "Quarter 3";
txt4.FontSize = 12;
txt4.FontWeight = FontWeights.Bold;
Grid.SetRow(txt4, 1);
Grid.SetColumn(txt4, 2);
// Add the sixth text cell to the Grid
TextBlock txt5 = new TextBlock();
Double db1 = new Double();
db1 = 50000;
txt5.Text = db1.ToString();
Grid.SetRow(txt5, 2);
Grid.SetColumn(txt5, 0);
// Add the seventh text cell to the Grid
TextBlock txt6 = new TextBlock();
Double db2 = new Double();
db2 = 100000;
txt6.Text = db2.ToString();
Grid.SetRow(txt6, 2);
Grid.SetColumn(txt6, 1);
// Add the final text cell to the Grid
TextBlock txt7 = new TextBlock();
Double db3 = new Double();
db3 = 150000;
txt7.Text = db3.ToString();
Grid.SetRow(txt7, 2);
Grid.SetColumn(txt7, 2);
// Total all Data and Span Three Columns
TextBlock txt8 = new TextBlock();
txt8.FontSize = 16;
txt8.FontWeight = FontWeights.Bold;
txt8.Text = "Total Units: " + (db1 + db2 + db3).ToString();
Grid.SetRow(txt8, 3);
Grid.SetColumnSpan(txt8, 3);
// Add the TextBlock elements to the Grid Children collection
myGrid.Children.Add(txt1);
myGrid.Children.Add(txt2);
myGrid.Children.Add(txt3);
myGrid.Children.Add(txt4);
myGrid.Children.Add(txt5);
myGrid.Children.Add(txt6);
myGrid.Children.Add(txt7);
myGrid.Children.Add(txt8);
// Add the Grid as the Content of the Parent Window Object
mainWindow.Content = myGrid;
mainWindow.Show ();

How to programmatically set tab order

I am building a window from code.
I add a header TextBlock and then some various elements for a listBox in which each element is made out of
Grid ---> children[0] a TextBlock to explain what is the element
---> children1 a TextBox or combobox to input data.
At the end a button.
After having generated put the focus on the first element (generally the first TextBox) so that the user can immediately input data. Up to that everything works.
--ADD--
I forgot to mention that every element = Grid = Textblock + TextBox or combobox, is an element of the parent listBox. So I would like to move from every textbox or combobox independently from the listbox element they are in.
After that I want the user to be able to move to next element (textbox or combobox) through TAB. So when generating the previous windows I use a counter and set
tb.TabIndex = tabIndex++;
or
ComboBox.TabIndex = tabIndex++;
Now the problem is that after having input data in the first TextBox when I press TAB the caret gets lost and so the focus...
---ADD2---
Here is the code:
private void PreparareTraceFieldGrid(ListBox lbTracefields, ObservableCollection<Tuple<string, object, object>> obc, bool IsReadOnly)
{
bool IsFocusSet = false;
/*---TITOLO---*/
OutlinedTextBlock otbTitle = CreateOtbForTraceFieldInputWindow(Languages.Word(eWords.InsertTracefields));
lbTracefields.Items.Add(otbTitle);
/*----CICLO----*/
int tabIndex = 0;
foreach (var item in obc)
{
Grid gridInternal = new Grid();
gridInternal.Background = Brushes.Transparent;
ColumnDefinition cd1 = new ColumnDefinition();
cd1.Width = new GridLength(300, GridUnitType.Pixel);
ColumnDefinition cd2 = new ColumnDefinition();
cd2.Width = new GridLength(1.0, GridUnitType.Star);
gridInternal.ColumnDefinitions.Add(cd1);
gridInternal.ColumnDefinitions.Add(cd2);
OutlinedTextBlock otb = CreateOtbForTraceFieldInputWindow(item.Item1);
otb.FontSize = easyRunData.OptionsGraphical.FontSize;
otb.Stroke = new SolidColorBrush(easyRunData.OptionsGraphical.StrokeColour);
otb.StrokeThickness = easyRunData.OptionsGraphical.StrokeSize;
Grid.SetColumn(otb, 0);
gridInternal.Children.Add(otb);
string strDataType = item.Item2.ToString();
eTraceFieldDataTypes eDataType = (eTraceFieldDataTypes)Enum.Parse(typeof(eTraceFieldDataTypes), strDataType);
switch (eDataType)
{
case eTraceFieldDataTypes.STRING:
case eTraceFieldDataTypes.FLOAT:
case eTraceFieldDataTypes.INTEGER:
case eTraceFieldDataTypes.STRING_READONLY:
TextBox tb = new TextBox();
tb.CaretBrush = Brushes.White;
tb.FontSize = easyRunData.OptionsGraphical.FontSize;
tb.MinWidth = 200;
tb.Height = easyRunData.OptionsGraphical.FontSize + 15;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.Background = Brushes.Transparent;
tb.Margin = new Thickness(10);
tb.TabIndex = tabIndex++;
tb.KeyDown += (senderEvent, args) => { AnalyzeTraceFields_IF_EMPTY(easyRunData.Tracefields.TraceFieldsUser, (Grid)lbTracefields.Parent); };
if (eDataType == eTraceFieldDataTypes.STRING_READONLY && !IsReadOnly)
tb.BorderBrush = Brushes.Yellow;
else
tb.BorderBrush = Brushes.Gainsboro;
Grid.SetColumn(tb, 1);
gridInternal.Children.Add(tb);
lbTracefields.Items.Add(gridInternal);
if (!IsFocusSet)
{
tb.Focus();
IsFocusSet = true;
}
break;
case eTraceFieldDataTypes.BOOL:
case eTraceFieldDataTypes.BOOL_READONLY:
Border brd = new Border();
brd.Margin = new Thickness(10);
brd.MinWidth = 200;
brd.Height = easyRunData.OptionsGraphical.FontSize + 15;
if (eDataType == eTraceFieldDataTypes.BOOL_READONLY && !IsReadOnly)
brd.BorderBrush = Brushes.Yellow;
else
brd.BorderBrush = Brushes.Gainsboro;
brd.BorderThickness = new Thickness(3);
ComboBox cmb = new ComboBox();
cmb.VerticalAlignment = VerticalAlignment.Center;
cmb.Background = Brushes.Transparent;
cmb.Items.Add(Languages.Word(eWords.True));
cmb.Items.Add(Languages.Word(eWords.False));
cmb.BorderBrush = Brushes.Gainsboro;
cmb.BorderThickness = new Thickness(3);
cmb.Margin = new Thickness(0);
cmb.TabIndex = tabIndex++;
cmb.DropDownClosed += (senderEvent, args) => { AnalyzeTraceFields_IF_EMPTY(easyRunData.Tracefields.TraceFieldsUser, (Grid)lbTracefields.Parent); };
Grid.SetColumn(brd, 1);
brd.Child = cmb;
gridInternal.Children.Add(brd);
lbTracefields.Items.Add(gridInternal);
if (!IsFocusSet)
{
cmb.Focus();
IsFocusSet = true;
}
break;
default:
break;
}
}

Accessing TextBlock in a grid with LINQ

I am dynamically generating rows in a XAML grid:
for (int i = 0; i < AssociatedSteps.Length; i++)
{
//if (i == 0 || AssociatedSteps[i].OriginPkg != AssociatedSteps[i-1].OriginPkg)
//{
//Define new Row to add
RowDef = new RowDefinition();
RowDef.Height = new GridLength(60);
//Add row definition to Grid
WorkPackageViewResults.RowDefinitions.Add(RowDef);
//Define the control that will be added to new row
Text1 = new TextBlock();
Text1.Text = AssociatedSteps[i].SF01;
Text1.Width = Settings.workPackageColumn5Width;
Text1.TextAlignment = TextAlignment.Center;
Text2 = new TextBlock();
Text2.Text = AssociatedSteps[i].SF10;
Text2.Width = Settings.workPackageColumn5Width;
Text2.TextAlignment = TextAlignment.Center;
Text3 = new TextBlock();
Text3.Text = AssociatedSteps[i].OriginPkg;
Text3.Width = Settings.workPackageColumn5Width;
Text3.TextAlignment = TextAlignment.Center;
Button1 = new Button();
Button1.Content = AssociatedSteps[i].Description;
Button1.Width = Settings.workPackageColumn5Width;
Button1.Click += new RoutedEventHandler(ProgressUpdateButton_Click);
Button1.Tag = AssociatedSteps[i].StepID;
//create stackpanel and define which row to add the stackpanel to
StackP = new StackPanel();
//StackP.Background = new SolidColorBrush(Colors.Wheat);
StackP.SetValue(Grid.RowProperty, i);
StackP.Orientation = Orientation.Horizontal;
StackP.Margin = new Thickness(0, 0, 0, 0);
PercentComplete = new TextBlock();
PercentComplete.Text = (Convert.ToDouble(AssociatedSteps[i].ToDateQty) / Convert.ToDouble(AssociatedSteps[i].MTOQty)).ToString();
PercentComplete.Width = Settings.workPackageColumn5Width;
PercentComplete.TextAlignment = TextAlignment.Center;
//add your control to the stackpanel
StackP.Children.Add(Text1);
StackP.Children.Add(Text2);
StackP.Children.Add(Text3);
StackP.Children.Add(Button1);
StackP.Children.Add(PercentComplete);
//add the stackpanel to the grid
WorkPackageViewResults.Children.Add(StackP);
}
I'm trying to use LINQ to get access to the grid being programatically updated above:
<Grid Name="WorkPackageViewResults">
</Grid>
I'm not seeing they type of options you would for a cell. I want to to access a particular rows PercentComplete TextBlock so I can update the text. How do I accomplish this?
Since there's only one StackPanel you could say e => e.GetType() == typeof(StackPanel). If you ever have many, then add a Name to the StackPanel and pull it by that.

How to display only row border of a grid (not column) using Border()

I am using c# in silverlight application.
I have a grid with 1 row and 3 columns.
There are 2 things that i am not able to know how to do:
(1) I have to display the boundaries of just row (not columns, only rows). How to do that?
Currently i have a grids like this:
//The p in function call below is yhe object obtained on deserialixing xml.
private static Grid GenerateGrid(Parameters p)
{
Grid myGrid = new Grid();
myGrid.Width = 650;
myGrid.HorizontalAlignment = HorizontalAlignment.Left;
myGrid.VerticalAlignment = VerticalAlignment.Top;
myGrid.ShowGridLines = false;
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(colDef1);
myGrid.ColumnDefinitions.Add(colDef2);
myGrid.ColumnDefinitions.Add(colDef3);
int totalRows = p.Parameter.Count() + p.Separator.Count();
for (int i = 0; i < totalRows; i++)
{
myGrid.RowDefinitions.Add(new RowDefinition());
}
return (myGrid);
}
Call to this function is :
XmlParameterClasses.Parameters parameter =
(XmlParameterClasses.Parameters)deserializer.Deserialize(reader);
Grid BigGrid = GenerateGrid(parameter);
My try to achieve is this: (I used Border to do this, see at the end of the function)
private static Grid GenerateComboBox(ViewModel.XmlParameterClasses.Parameter param, int LoopCount, Grid g)
{ //param is the object of the class Parameter
StackPanel sp1 = new StackPanel(); //These three stackpanels are inside the grid cell
StackPanel sp2 = new StackPanel();
StackPanel sp3 = new StackPanel();
ComboBox cb = new ComboBox();
TextBlock txtblk1 = new TextBlock();
TextBlock txtblkLabel = new TextBlock();
////////////////////////////////////
//Label Display
txtblkLabel.Text = param.Label;
txtblkLabel.VerticalAlignment = System.Windows.VerticalAlignment.Center;
txtblkLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
txtblkLabel.TextAlignment = System.Windows.TextAlignment.Center;
txtblkLabel.FontWeight = FontWeights.Bold;
txtblkLabel.FontSize = 15;
txtblkLabel.FontStyle = FontStyles.Normal;
txtblkLabel.Padding = new Thickness(5, 10, 5, 10);
sp1.Orientation = Orientation.Horizontal;
sp1.Children.Add(txtblkLabel);
sp1.Width = 100;
sp1.Height = 50;
Grid.SetRow(sp1, LoopCount);
Grid.SetColumn(sp1, 0);
g.Children.Add(sp1);
foreach(var item in param.Component.Attributes.Items) {
cb.Items.Add(item);
}
cb.SelectionChanged += new SelectionChangedEventHandler(comboBox1_SelectionChanged);
cb.SelectedIndex = cb.Items.Count - 1;
//For text Display
txtblk1.Text = cb.SelectedValue.ToString() + " millions";
txtblk1.VerticalAlignment = System.Windows.VerticalAlignment.Center;
txtblk1.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
txtblk1.TextAlignment = System.Windows.TextAlignment.Center;
txtblk1.FontWeight = FontWeights.Bold;
txtblk1.FontSize = 15;
txtblk1.FontStyle = FontStyles.Normal;
txtblk1.Padding = new Thickness(5, 10, 5, 10);
sp2.Orientation = Orientation.Horizontal;
sp2.Children.Add(txtblk1);
Grid.SetColumn(sp2, 2);
Grid.SetRow(sp2, LoopCount);
g.Children.Add(sp2);
//For combo box display
cb.Width = 45;
cb.Height = 25;
sp3.Orientation = Orientation.Horizontal;
sp3.Children.Add(cb);
sp3.Width = 50;
sp3.Height = 50;
Grid.SetColumn(sp3, 1);
Grid.SetRow(sp3, LoopCount);
g.Children.Add(sp3);
////////////Here is the Border Display ////////////////////////////
Border rect = new Border();
rect.Width = g.Width;
rect.Height = g.Height;
rect.BorderThickness = new Thickness(5);
rect.BorderBrush = new SolidColorBrush(Colors.Black);
g.Children.Add(rect);
////////////////////////////////////////////////////////////////////
return (g);
}
but the output obtained is like this : (It just cover the border of first cell not the other two in that row, whereas i just want one border over one row(not over the column in that row, just row boundary))
Could some one please help me in achieving this step ? Is it possible to implement what i want trying to do?
Note: Please note that code has to be implemented using c# only , not xaml.
I have done it by creating a grid of 1 column and rows (instead of 3*3 cell it must be 1*3 (row*column)). Then creating Border in each row and then again creating grid with 1 row and 3 columns and then creating border of this small grid.
code is:
Border rect = new Border();
rect.Width = g.Width;
rect.Height = g.Height;
rect.BorderThickness = new Thickness(2);
rect.BorderBrush = new SolidColorBrush(Colors.Black);
Grid childGrid = new Grid();
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
childGrid.ColumnDefinitions.Add(colDef1);
childGrid.ColumnDefinitions.Add(colDef2);
childGrid.ColumnDefinitions.Add(colDef3);
TextBlock txtblk3 = new TextBlock();
var border = new Border()
{
Background = new SolidColorBrush(Colors.LightGray)
};
border.Height = 14;
var border1 = new Border()
{
Background = new SolidColorBrush(Colors.White)
};
border1.Height = 14;
Grid.SetColumnSpan(border, 3);
Grid.SetRow(childGrid, LoopCount);
childGrid.Children.Add(border);
txtblk3.FontSize = 14;
txtblk3.FontWeight = FontWeights.Bold;
txtblk3.Text = param.Separator[SeparatorPosition];
Grid.SetColumn(border1, 1);
Grid.SetRow(border1,LoopCount);
border1.Child = txtblk3;
childGrid.Children.Add(border1);
g.Children.Add(childGrid);
return (g);
Where "g" has only 1 column and "LoopCount" numbers of row. And it worked for me.
You should override CellPainting event of DataGridView control as the code snippet below:
private void grid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
e.AdvancedBorderStyle.Left = DataGridViewAdvancedCellBorderStyle.None;
e.AdvancedBorderStyle.Right = DataGridViewAdvancedCellBorderStyle.None;
}

How to set ScrollViewer or scroll (dynamically created grid)?

Here I'm dynamically creating grid on form. The code is working fine but I want this grid in scroll viewer or scroll bar (vertical). Can any one tell me how to set scroll in this code.
Grid DynamicGrid = new Grid();
DynamicGrid.Width = 400;
DynamicGrid.HorizontalAlignment = HorizontalAlignment.Right;
DynamicGrid.VerticalAlignment = VerticalAlignment.Top;
DynamicGrid.Margin = new Thickness(50);
DynamicGrid.ShowGridLines = false;
DynamicGrid.Background = new SolidColorBrush(Colors.LightSteelBlue);
// Create Columns
ColumnDefinition gridCol1 = new ColumnDefinition();
DynamicGrid.ColumnDefinitions.Add(gridCol1);
// Create Rows
RowDefinition gridRow1 = new RowDefinition();
gridRow1.Height = new GridLength(30);
DynamicGrid.RowDefinitions.Add(gridRow1);
TextBlock txtBlock2 = new TextBlock();
txtBlock2.Text = "Age";
txtBlock2.FontSize = 14;
txtBlock2.FontWeight = FontWeights.Bold;
txtBlock2.Foreground = new SolidColorBrush(Colors.Green);
txtBlock2.VerticalAlignment = VerticalAlignment.Top;
Grid.SetRow(txtBlock2, 0);
Grid.SetColumn(txtBlock2, 1);
TextBlock ageText = new TextBlock();
ageText.Text = "33";
ageText.FontSize = 12;
ageText.FontWeight = FontWeights.Bold;
Grid.SetRow(ageText, 1);
Grid.SetColumn(ageText, 1);
// Display grid into a Window
window.Content = DynamicGrid;
I think the easiest way to do that is to include the Grid into a ScrollViewer:
ScrollViewer viewer = new ScrollViewer();
viewer.Content = DynamicGrid;
Window.Content = viewer;
Best regards,

Categories

Resources