Swapping control position in TableLayoutPanel - c#

EDIT:
Okay so for clarity I will improve my information a bit more:
I have a TableLayoutView (I will call this tlv) that has 5 fixed columns, and x + 2 rows. The first row of tlv contains labels in each cell for header purposes. I dynamically add more rows onto tlv and so that it why it has a variable amount of rows (plus the initial header row which is never removed).
As another tiny small complication, I also keep an empty row entry at the bottom of tlv which I must keep because I use it for other functionality.
To visualise what I have just said, this is an example of tlv consisting with 4 entries (numbered), the header row (H's) and the placeholder row (P's).
HHHHH
11111
22222
33333
44444
PPPPP
I want to go from that, to say, if I wanted to swap entry 2 and 3 the output would be:
HHHHH
11111
33333
22222
44444
PPPPP
The code I have so far is as follows:
for (int j = 0; j < 5; j++)
{
TableLayoutPanelCellPosition tablePosition1 = new
TableLayoutPanelCellPosition(j, rowIndex + 1);
Control moveControl1 = queuedFiles.GetControlFromPosition(j, rowIndex);
queuedFiles.SetCellPosition(moveControl1, tablePosition1);
TableLayoutPanelCellPosition tablePosition2 = new
TableLayoutPanelCellPosition(j, rowIndex);
Control moveControl2 = queuedFiles.GetControlFromPosition(j, rowIndex + 1);
queuedFiles.SetCellPosition(moveControl2, tablePosition2);
if (j.Equals(0))
{
moveControl1.Text = (rowIndex + 1).ToString();
moveControl2.Text = (rowIndex).ToString();
}
}
However this code doesn't work and for the example above it produces:
HHHHH
11111
33222
22333
44444
PPPPP
What I believe is happening is tlv is automatically organising it's contents itself during the process of moving them around (maybe to fill vacant spaces?).
rowIndex above is the index of the target row which must be swapped with the row below it. I don't need to worry about checking if there is only 1 row or if it is the last row because I have done that already. Ignore changing the text too, I just need a pointer as to how I can achieve the intended result!
Thank you for absolutely any help you can give :)

The following code does the job:
Code
using System;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// some content
var panel = new TableLayoutPanel
{
Dock = DockStyle.Fill,
ColumnCount = 5,
RowCount = 2
};
for (var y = 0; y < 2; y++)
for (var x = 0; x < 5; x++)
{
var control = new Button {Text = $#"X = {x}, Y = {y}"};
panel.Controls.Add(control, x, y);
}
// swap button
var button = new Button
{
Dock = DockStyle.Fill,
Text = #"Clicky !"
};
button.Click += (o, args) =>
{
var dictionary = panel.Controls
.Cast<Control>()
.ToDictionary(k => k, v => panel.GetCellPosition(v));
foreach (var pair in dictionary)
{
var position = pair.Value;
position.Row ^= 1; // simple row swap
panel.SetCellPosition(pair.Key, position);
}
};
// add to form
var container = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Horizontal,
SplitterWidth = 5,
BorderStyle = BorderStyle.Fixed3D
};
container.Panel1.Controls.Add(panel);
container.Panel2.Controls.Add(button);
Controls.Add(container);
}
}
}
Before
After
Note
Next time you ask a question, post a Minimal, Complete, and Verifiable example to maximize your chances of getting an answer !
As on why your code didn't work, see previous sentence, e.g what was rowIndex etc ?
Edit
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
const int cols = 5;
const int rows = 6;
// setup layout
var tlp = new TableLayoutPanel
{
ColumnCount = cols,
RowCount = rows,
Dock = DockStyle.Fill,
GrowStyle = TableLayoutPanelGrowStyle.FixedSize
};
for (var i = 0; i < cols; i++)
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100.0f / cols));
// add header
var label = new Label
{
Text = #"My Header",
BackColor = Color.Red,
Dock = DockStyle.Fill,
TextAlign = ContentAlignment.MiddleCenter
};
tlp.Controls.Add(label);
tlp.SetColumn(label, 0);
tlp.SetRow(label, 0);
tlp.SetColumnSpan(label, cols);
// add some cells
var yMin = 1;
var yMax = 5;
var xMin = 0;
var xMax = cols;
for (var y = yMin; y < yMax; y++)
for (var x = xMin; x < xMax; x++)
{
var color = Color.FromArgb(
255 / (xMax - xMin) * (x - xMin),
128,
255 / (yMax - yMin) * (y - yMin)
);
var label1 = new Label
{
Text = $#"X = {x}, Y = {y}",
BackColor = color,
ForeColor = Color.White,
Dock = DockStyle.Fill,
TextAlign = ContentAlignment.MiddleCenter,
Margin = DefaultMargin
};
tlp.Controls.Add(label1, x, y);
}
// add swapper
var button = new Button
{
Text = #"Clicky !",
Dock = DockStyle.Fill
};
button.Click += (o, args) =>
{
var srcRow = 2;
var tgtRow = 3;
var controls = tlp.Controls.Cast<Control>().ToArray();
var array1 = controls.Where(s => tlp.GetRow(s) == srcRow).ToArray();
var array2 = controls.Where(s => tlp.GetRow(s) == tgtRow).ToArray();
foreach (var control in array1)
tlp.SetCellPosition(control, new TableLayoutPanelCellPosition(tlp.GetColumn(control), tgtRow));
foreach (var control in array2)
tlp.SetCellPosition(control, new TableLayoutPanelCellPosition(tlp.GetColumn(control), srcRow));
};
// pack things up
var sc = new SplitContainer
{
Orientation = Orientation.Horizontal,
BorderStyle = BorderStyle.Fixed3D,
Dock = DockStyle.Fill
};
sc.Panel1.Controls.Add(tlp);
sc.Panel2.Controls.Add(button);
Controls.Add(sc);
}
}
}

Related

How to calculate cell height [that has long text] when printing DataGridView in C#

I searched but didn't find how to set the cell height when printing DataGridView when the cell has long text.
I didn't find one result that concentrate how to calculate the height with long text. And I don't want to use 3rd party DLL file that print it with right cell height.
I use this code to calculate the height but text always cut and short text has lower cell height that on DGV.
var tallestHeight = 0;
foreach (DataGridViewCell cell in GridRow.Cells)
{
if (!cell.Visible) { continue; }
var s = e.Graphics.MeasureString(cell.FormattedValue.ToString(), dataGridView1.Font);
var tempHeight = (int)(s.Height * Math.Ceiling(s.Width / dataGridView1.Columns[cell.ColumnIndex].Width));
if (tempHeight > tallestHeight)
{
tallestHeight = tempHeight;
}
tallestHeight = (tallestHeight < 22) ? 22 : tallestHeight;
}
iCellHeight = tallestHeight;
I want when I print DataGridView to printer to show all the text in all cells without cutting. Long text increase the row height and if no long text row's height stays unchanged.
I have row height = 22
Text wrap for my DataGridView is enabled
Edit1:
Here is my DataGridView properties
Here is how i print my DataGridView: PrintDGV Class that i use
My DGV appears
Print preview
Yellow highlighted text isn't complete Full text is First Middle lastname- some text- 0130011511478- تجربةة 7427/01300/8346584584563846
The text below it complete.
How to show the first row at full?
Apart from the grid settings, you need to use the output sizes to calculate the adequate height of each row to fit their contents. Also, calling a MeasureString method overload that takes StringFormat is necessary to get more accurate result.
I see in the printout image above you are dividing the MarginBounds.Width by the visible cells. Thus, the following:
Calculate
Create a method to calculate and return the proper height of each row.
// +
using System.Linq;
private int GetRowHeight(
Graphics g,
DataGridViewRow row,
Rectangle bounds,
StringFormat sf,
int minHeight = 22)
{
var cells = row.Cells.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible);
if (cells == null) return minHeight;
var cell = cells.Aggregate((DataGridViewTextBoxCell)null, (x, y) => x != null &&
x.FormattedValue.ToString().Length > y.FormattedValue.ToString().Length ? x : y);
if (cell == null) return minHeight;
var h = g.MeasureString(cell.FormattedValue.ToString(),
row.DataGridView.Font,
new SizeF(bounds.Width / cells.Count(), bounds.Height),
sf).ToSize().Height;
return Math.Max(h + 6, minHeight); // 6 for top and bottom margins...
}
Call
Caller example and class variables to track the printing...
// +
using System.Drawing.Printing;
private int rowIndex;
private int cellCount;
private int pageNumber;
private readonly PrintDocument printDoc;
// ...
// ctor
public YourForm()
{
InitializeComponent();
printDoc = new PrintDocument();
printDoc.PrintPage += OnPrintPage;
}
// Cleanup
private void YourForm_FormClosed(object sender, FormClosedEventArgs e)
{
printDoc.Dispose();
}
// Preview
private void btnPrintPreview(object sender, EventArgs e) => Print(true);
// Print
private void btnPrint(object sender, EventArgs e) => Print();
// Print Routine
private void Print(bool preview = false)
{
rowIndex = 0;
cellCount = 0;
pageNumber = 0;
var rows = dataGridView1.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => !r.IsNewRow);
if (rows != null)
cellCount = rows.Cells
.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible)
.Count();
if (cellCount == 0)
{
MessageBox.Show("Nothing to print...");
return;
}
printDoc.DefaultPageSettings.Landscape = true;
if (preview)
{
using (var pd = new PrintPreviewDialog())
{
pd.Document = printDoc;
pd.ShowDialog();
}
}
else
{
using (var pd = new PrintDialog())
{
pd.Document = printDoc;
if (pd.ShowDialog() == DialogResult.OK)
pd.Document.Print();
}
}
}
Print
PrintDocument.PrintPage event example.
// +
using System.Drawing.Text;
private void OnPrintPage(object sender, PrintPageEventArgs e)
{
var w = e.MarginBounds.Width / cellCount;
var x = e.MarginBounds.X;
var y = e.MarginBounds.Y;
int h;
Rectangle rec;
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
// Maybe you need to set this? I see Arabic text in the images.
// sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
// Uncomment to print the headers in the first page only.
//if (pageNumber == 0)
//{
h = dataGridView1.RowTemplate.Height;
foreach (var col in dataGridView1.Columns
.OfType<DataGridViewTextBoxColumn>()
.Where(c => c.Visible))
{
rec = new Rectangle(x, y, w, h);
e.Graphics.FillRectangle(Brushes.Gainsboro, rec);
e.Graphics.DrawString(
col.HeaderText,
col.DataGridView.Font,
Brushes.Black,
rec,
sf);
e.Graphics.DrawRectangle(Pens.Black, rec);
x += w;
}
x = e.MarginBounds.X;
y += h;
//}
for (var i = rowIndex; i < dataGridView1.RowCount; i++)
{
var row = dataGridView1.Rows[i];
if (row.IsNewRow) break;
h = GetRowHeight(e.Graphics, row, e.MarginBounds, sf);
if (h > e.MarginBounds.Height)
{
MessageBox.Show("Insufficient height.");
e.Cancel = true;
return;
}
foreach (var cell in row.Cells
.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible))
{
rec = new Rectangle(x, y, w, h);
if (rec.Bottom > e.MarginBounds.Bottom)
{
pageNumber++;
rowIndex = i;
e.HasMorePages = true;
return;
}
e.Graphics.DrawString(
cell.FormattedValue.ToString(),
dataGridView1.Font,
Brushes.Black,
rec,
sf);
e.Graphics.DrawRectangle(Pens.Black, rec);
x += rec.Width;
}
x = e.MarginBounds.X;
y += h;
}
}
}
Output

Add views to a TableLayout

What do I want to achieve?
My goal is to create a sudoku field programmatically, so I want to add 9x9 EditText-views to my existing TableLayout.
What is my problem?
Easy said: The EditText-views are not showing up.
What have I tried?
Well.. my google attempts could be recognized as a DDOS-Attack.. ;)
But seriously, I googled a lot, read some documentations etc. but could not find appropriate information solving my problem.
My Sudoku activiy code:
public class Sudoku : Activity
{
private EditText[,] tbs;
private TableLayout grid;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
//set view
SetContentView(Resource.Layout.Sudoku);
//initializations
tbs = new EditText[9,9];
grid = FindViewById<TableLayout> (Resource.Id.grid);
//preparation
prepareControls ();
}
private void prepareControls()
{
int size = Conversion.PixelsToDp(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.Density) / 15;
int x_default = 10;
int x = x_default;
int y = x_default;
int margin = 4;
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams (size, size);
for (int row = 0; row < 9; row++)
{
TableRow trow = new TableRow (this);
for (int col = 0; col < 9; col++)
{
//lparams.LeftMargin = x;
//lparams.TopMargin = y;
EditText tb = new EditText (this);
tb.SetHeight (size);
tb.SetWidth (size);
tb.Gravity = GravityFlags.Center;
tb.SetTextColor (Color.Argb (1, 75, 75, 75));
tb.SetBackgroundColor (Color.White);
tb.LayoutParameters = lparams;
tbs[col, row] = tb;
//layout.AddView (tb, lparams);
trow.AddView (tb);
x += size;
if ((col + 1) % 3 == 0)
{
x += margin;
}
if ((col + 1) % 9 == 0)
{
y += size;
x = x_default;
}
}
if ((row + 1) % 3 == 0)
{
y += margin;
}
grid.AddView (trow);
}
}
}
Additional information
Environment: Xamarin
Language: C#
API Level: API 15
I appreciate any help!

Why does my dynamically created GroupBox place its RadioButtons too far right on subsequent usages?

I am adding various dynamically created controls to a panel, based on what the user selects. If a Groupbox, with associated RadioButtons, is the first control, it looks fine:
...but if it's anything other than that, the associated radio buttons seem right-aligned instead of left-aligned, as seen above, and the groupbox is too wide, to boot.
Here is the pertinent code (RepaintMockupPanel() is called when the user opts to see what his mockup looks like at any time, and getGroupBox() is the method it calls that should be where the problem lies, but I can't see it.
private void RepaintMockupPanel(Control padre)
{
const string BTN = "BUTTON";
const string CKBX = "CHECKBOX";
const string EDTTXT = "EDITTEXT";
const string RADGRP = "RADIOGROUP";
const string SPNR = "SPINNER";
const string TXTVU = "TEXTVIEW";
const int LEFT_STARTING_POINT = 4;
const int STANDARD_PADDING = 4;
int currentLeft = LEFT_STARTING_POINT;
string currentSel;
string currentSettings;
ComboBox cmbx;
Label lbl;
try
{
TabPage tp = padre as TabPage;
string panelName = tp.Name.Replace("tabPage", "panel");
Panel p = tp.Controls[panelName] as Panel;
p.Controls.Clear();
for (int i = 0; i < p.Controls.Count; i++)
{
p.Controls[i].Dispose();
}
//cmbxRow0Element0 and lblRow0Element0 to cmbxRow11Element5 and lblRow11Element5
int rowNum = getRowNum(panelName);
for (int i = 0; i < WIDGETS_PER_TABPAGE; i++)
{
cmbx = tp.Controls[string.Format("cmbxRow{0}Element{1}", rowNum, i)] as ComboBox;
lbl = tp.Controls[string.Format("lblRow{0}Element{1}", rowNum, i)] as Label;
if (cmbx.SelectedIndex < 0) continue;
currentSel = cmbx.SelectedItem.ToString().ToUpper();
currentSettings = lbl.Text;
// Possible vals (Android on left, Windows equivalents on the right:
//Button ""
//CheckBox ""
//EditText TextBox
//RadioGroup GroupBox (w. RadioButtons nested within)
//Spinner ComboBox
//TextView Label
if ((currentSel.Length > 0) && (currentSettings.Length > 0))
{
if (currentSel.Equals(BTN))
{
Button btn = getButton(currentSettings, currentLeft);
p.Controls.Add(btn);
currentLeft += btn.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(CKBX))
{
CheckBox ckbx = getCheckBox(currentSettings, currentLeft);
p.Controls.Add(ckbx);
currentLeft += ckbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(EDTTXT))
{
TextBox txtbx = getTextBox(currentSettings, currentLeft);
p.Controls.Add(txtbx);
currentLeft += txtbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(RADGRP))
{
GroupBox grpbx = getGroupBox(currentSettings, currentLeft);
p.Controls.Add(grpbx);
currentLeft += grpbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(SPNR))
{
ComboBox cmbxDyn = getComboBox(currentSettings, currentLeft);
p.Controls.Add(cmbxDyn);
currentLeft += cmbxDyn.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(TXTVU))
{
Label lblDyn = getLabel(currentSettings, currentLeft);
p.Controls.Add(lblDyn);
currentLeft += lblDyn.Width + STANDARD_PADDING;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private GroupBox getGroupBox(string currentSettings, int curLeftVal)
{
// "apple~orange~peach~True (must look for "enclose group in a black box" as the last val (ignore for the quick-and-dirty mockup, though))
// Adapted from Pierre's answer at http://stackoverflow.com/questions/23944419/why-is-only-the-first-radiobutton-being-added-to-the-groupbox
IList<string> grpbxVals = new List<string>(currentSettings.Split('~'));
GroupBox gb = new GroupBox { Height = 60, Location = new Point(curLeftVal, 0) };
gb.AutoSize = true;
int radButtonYVal = 0;
for (int i = 0; i < grpbxVals.Count() - 1; i++)
{
//gb.Controls.Add(new RadioButton { Text = grpbxVals[i], Location = new Point(curLeftVal, radButtonPosition) });
gb.Controls.Add(new RadioButton { Text = grpbxVals[i], Location = new Point(gb.Location.X+2, radButtonYVal) });
radButtonYVal += new RadioButton().Height;
}
return gb;
}
The getGroupBox() method is INDEED where the issue lies.
As a Container, GroupBox has its own canvas upon which its child controls are drawn, so when you create a control with an X value of 5, it means it's 5 from the left of the GroupBox, NOT from the left of the form. It's absolute value on the form would be it's own X value (say in this case 5) plus the X value of the GroupBox (which we'll assume has a Left value of 25) for an absolute positon of being 30 from the Left.
This is why your example shows the radio buttons pushed over so far: if you examine the distance between the left edge of the RadioButtons in relation to the left edge of their containing GroupBox, it should be about the same distance as the left edge of the GroupBox from the left edge of ITS container.
Why not use a TableLayoutPanel or FlowLayoutPanel to automatically position the controls, you can insert with fill dock the GroupBox.
Then you just need to add the controls to ... LayoutPanel and positioned automatically.
You have several options to control the rows and / or columns of the TableLayoutPanel
And as other controls to control flow into the FlowLayoutPanel
Here a example using layout panel, place a Button docked Top, and a empty TabControl docked Fill, and try this code
private void button1_Click(object sender, EventArgs e)
{
for (int t = 0; t < 4;t++ )
tabControl1.TabPages.Add(CreateTabPage(t));
}
private TabPage CreateTabPage(int t)
{
TabPage result = new TabPage()
{
Text=string.Format("TabPage {0}",t)
};
FlowLayoutPanel flp = new FlowLayoutPanel()
{
Dock = DockStyle.Fill,
AutoScroll = true,
};
for (int i = 0; i < 10; i++)
{
flp.Controls.Add(CreateGroupBox(i));
}
result.Controls.Add(flp);
return result;
}
private Control CreateGroupBox(int i)
{
GroupBox result = new GroupBox()
{
Text = string.Format("GroupBox {0}", i),
Width = 150,
Height = 100
};
FlowLayoutPanel flp = new FlowLayoutPanel()
{
Dock = DockStyle.Fill,
WrapContents = false,
AutoScroll = true,
FlowDirection=FlowDirection.TopDown
};
CreateRadios(flp, i);
result.Controls.Add(flp);
return result;
}
private void CreateRadios(FlowLayoutPanel flp, int i)
{
for (int c = 0; c < 10; c++) {
flp.Controls.Add(new RadioButton()
{
Text = string.Format("RadioButton {0} in {1}", c, i)
});
}
}
Tricycle Omnivore was right; this works:
int radButtonYVal = 4;
int leftVal = 4;
for (int i = 0; i < grpbxVals.Count() - 1; i++)
{
gb.Controls.Add(new RadioButton { Text = grpbxVals[i], AutoSize = true, Location = new Point(leftVal, radButtonYVal) });
radButtonYVal += new RadioButton().Height -4; // the "-4" is a kludge to scrunch the radiobuttons together a bit
}

Adding controls from foreach loop

I am trying to add controls to a panel from a foreach loop.
When i press the button i want every element from a array to show as checkbox. This is wordking fine, then i want a numeric updown behind the checkbox so users can select a value.
The code for creating the checkboxes works just fine, for every item in my array it displays e checkbox. But it only shows 1 NumericUpDown.
Can anybody tell me why it only shows 1 numeric updown, while it shows all of the checkboxes?
Here is my code:
private void bierButton_Click(object sender, EventArgs e)
{
int height = 1;
int padding = 10;
int i = 0;
int x = 0;
CheckBox[] chk = new CheckBox[10];
NumericUpDown[] nmr = new NumericUpDown[10];
orderBox.Clear();
hideBtn();
foreach (string bieren in Drinks.bier)
{
chk[i] = new CheckBox();
nmr[i] = new NumericUpDown();
chk[i].Name = i.ToString();
chk[i].Text = Drinks.bier[i];
chk[i].TabIndex = i;
chk[i].AutoCheck = true;
chk[i].Bounds = new Rectangle(10, 0 + padding + height, 200, 22);
panel1.Controls.Add(chk[i]);
testPanel.Controls.Add(nmr[i]);
height += 22;
i++;
}
}
It appears you are not updating the position of your NumericUpDown controls.
All of them are there, they are just on top of one another.
Consider this change:
private void bierButton_Click(object sender, EventArgs e)
{
int height = 1;
int padding = 10;
int i = 0;
int x = 0;
CheckBox[] chk = new CheckBox[10];
NumericUpDown[] nmr = new NumericUpDown[10];
orderBox.Clear();
hideBtn();
foreach (string bieren in Drinks.bier)
{
chk[i] = new CheckBox();
nmr[i] = new NumericUpDown();
chk[i].Name = i.ToString();
chk[i].Text = bieren; // Drinks.bier[i];
chk[i].TabIndex = i;
chk[i].AutoCheck = true;
chk[i].Bounds = new Rectangle(10, 0 + padding + height, 200, 22);
// Start New Code
nmr[i].Bounds = new Rectangle(10, 0 + padding + height, 200, 22);
// End New Code
panel1.Controls.Add(chk[i]);
testPanel.Controls.Add(nmr[i]);
height += 22;
i++;
}
}
I also changed one line to chk[i].Text = bieren;.

WPF C# DynamicDataDisplay - Changing the DateTimeAxis Color

I'd like to know how could I change the color of the date time axis of my d3 chartplotter.
The color that I want to change is the brown color and the white background color between the two bars.
If i do that :
It only changes the thing above the first brown bar.
Is it possible to change the color of these two bars ?
Curiously, I've happened to be trying to do the same thing. It turns out those colours are hard-coded in MayorDateTimeLabelProvider.cs (I've noted the lines in comments below). If you're using the compiled DLL then there is no way to change the values. Personally, D3 is so immature that I keep my own build of it and make changes to extend it as needed (such as in this case!).
public override UIElement[] CreateLabels(ITicksInfo<DateTime> ticksInfo)
{
object info = ticksInfo.Info;
var ticks = ticksInfo.Ticks;
UIElement[] res = new UIElement[ticks.Length - 1];
int labelsNum = 3;
if (info is DifferenceIn)
{
DifferenceIn diff = (DifferenceIn)info;
DateFormat = GetDateFormat(diff);
}
else if (info is MayorLabelsInfo)
{
MayorLabelsInfo mInfo = (MayorLabelsInfo)info;
DifferenceIn diff = (DifferenceIn)mInfo.Info;
DateFormat = GetDateFormat(diff);
labelsNum = mInfo.MayorLabelsCount + 1;
//DebugVerify.Is(labelsNum < 100);
}
DebugVerify.Is(ticks.Length < 10);
LabelTickInfo<DateTime> tickInfo = new LabelTickInfo<DateTime>();
for (int i = 0; i < ticks.Length - 1; i++)
{
tickInfo.Info = info;
tickInfo.Tick = ticks[i];
string tickText = GetString(tickInfo);
Grid grid = new Grid
{
Background = Brushes.Beige // **** HARD CODED HERE
};
Rectangle rect = new Rectangle
{
Stroke = Brushes.Peru, // **** AND HERE
StrokeThickness = 2
};
Grid.SetColumn(rect, 0);
Grid.SetColumnSpan(rect, labelsNum);
for (int j = 0; j < labelsNum; j++)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
grid.Children.Add(rect);
for (int j = 0; j < labelsNum; j++)
{
var tb = new TextBlock
{
Text = tickText,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 3, 0, 3)
};
Grid.SetColumn(tb, j);
grid.Children.Add(tb);
}
ApplyCustomView(tickInfo, grid);
res[i] = grid;
}
return res;
}

Categories