Draw three grids of user controls in VB.NET - vb.net

I have one user control of size 25x25 and I want to duplicate it into three separate 10x10 grids which I can change the location of on my form.
I'm making a pandemic simulation so the three grids represent the three countries and I will change the colour of the user control depending on the infection status of the grid square.
I've been playing around with this for a long time but I cannot get it to work, when I use Me.Controls.Add(UserControl) it overwrites the previous one and I'm left with only one user control on the form.
Any help appreciated, thanks.

Below is a method that will create grid and you can place arbitrary controls into "cells" of this "grid".
To run this, paste this code into any button handler and it will do everything it needs.
I don't know if this is exact solution but you may get something out of it. It would be helpful if you could make a mock of your screen in different states, so we understand what you actually want.
Call method DoAGrid on some button handler:
DoAGrid(bool.Parse(_txtTest.Text)); // type true or false in txt
The methos
private void DoAGrid(bool isTest)
{
const int size = 30; // I give 2 for controll padding
const int padding = 20; // x and y starting padding
Point[,] grid = new Point[10,10]; // x and y of each control
List<Control> btns = null;
if (isTest) btns = new List<Control>(100);
for (int x = 1; x < 11; x++)
{
for (int y = 1; y < 11; y++)
{
grid[x - 1, y - 1] = new Point(padding + x*size - 30 - 1, padding + y*size - 30 - 1); // 30 - 1 --> size + 2
if (isTest)
{ // this test will add all avail buttons so you can see how grid is formed
Button b = new Button();
b.Size = new Size(size, size);
b.Text = "B";
b.Location = grid[x - 1, y - 1];
btns.Add(b);
}
}
}
Form f = new Form();
f.Size = new Size(1000, 1000);
if (isTest)
{
f.Controls.AddRange(btns.ToArray());
}
else
{
// Add controls to random grid cells
Button b1 = new Button();
b1.Size = new Size(size, size);
b1.Text = "B1";
b1.Location = grid[3, 3];
Button b2 = new Button();
b2.Size = new Size(size, size);
b2.Text = "B2";
b2.Location = grid[5, 5];
Button b3 = new Button();
b3.Size = new Size(size, size);
b3.Text = "B3";
b3.Location = grid[8, 8];
Button b4 = new Button();
b4.Size = new Size(size, size);
b4.Text = "B4";
b4.Location = grid[8, 9];
Button b5 = new Button();
b5.Size = new Size(size, size);
b5.Text = "B5";
b5.Location = grid[9, 8];
Button b6 = new Button();
b6.Size = new Size(size, size);
b6.Text = "B6";
b6.Location = grid[9, 9];
f.Controls.AddRange(new Button[] { b1, b2, b3, b4, b5, b6 });
}
f.ShowDialog();
}

Related

displaying alert dialog in the correct location within a recyclerview

I'm making a custom button that when you long press on it a dialog will appear with a list of options to choose from.
The custom button works as it should, however, I'm having some trouble wrangling the dialog to show up exactly where I want it to.
this is the code that displays the dialog.
private void ShowReactionsDialog()
{
var context = Context;
var inflater = (LayoutInflater) context.GetSystemService(Context.LayoutInflaterService);
var dialogView = inflater.Inflate(Resource.Layout.react_dialog_layout, null);
var linearLayoutManager = new LinearLayoutManager(context)
{
Orientation = LinearLayoutManager.Horizontal
};
var adapter = new ReactionAdapter(_reactionList);
adapter.OnItemClicked += (sender, currentReaction) =>
{
UpdateReactButtonByReaction(currentReaction);
_reactAlertDialog.Cancel();
};
var rvReactions = dialogView.FindViewById<RecyclerView>(Resource.Id.reaction_rvReactions);
rvReactions.HasFixedSize = true;
rvReactions.SetLayoutManager(linearLayoutManager);
rvReactions.SetItemAnimator(new DefaultItemAnimator());
rvReactions.SetAdapter(adapter);
var dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.SetView(dialogView);
_reactAlertDialog = dialogBuilder.Create();
_reactAlertDialog.RequestWindowFeature((int)WindowFeatures.NoTitle);
var window = _reactAlertDialog.Window;
window.SetBackgroundDrawableResource(Resource.Drawable.react_dialog_shape);
window.SetDimAmount(0);
// Setup dialog gravity and dynamic position
var windowManagerAttributes = window.Attributes;
windowManagerAttributes.Gravity = GravityFlags.AxisSpecified;
windowManagerAttributes.X = (int) GetX() + (Width / 2);
windowManagerAttributes.Y = (int) GetY() + (Height / 2);
_reactAlertDialog.Show();
var dialogWidth = GetIconSize() * _reactionList.Count;
if (dialogWidth > GetScreenMaxWidth())
{
dialogWidth = GetScreenMaxWidth();
}
window.SetLayout(dialogWidth, ViewGroup.LayoutParams.WrapContent);
}
I've tried messing with the gravity and the X & Y coordinates but it just wants to either go too high up or too low down, there's no consistent location it's sticking to. I want it to be above the button that's getting long tapped.
You can use the following code to make the AlertDialog show above the button.
int[] location = new int[2];
AndroidX.AppCompat.App.AlertDialog alertDialog = builder.Create();
Window window = alertDialog.Window;
WindowManagerLayoutParams attributes = window.Attributes;
//Get the location of the button and location[0] is X and location[1] is Y
button.GetLocationInWindow(location);
//Set the height of the AlertDialog
int height = 400;
int a = button.Height / 2;
int c = location[1];
//Get the distance of top
attributes.Y = c - a - height;
window.Attributes = attributes;
//Set the AlertDialog location according to the distance of top
window.SetGravity(GravityFlags.Top);
alertDialog.Show();
//Set the Width and Hight of the AlertDialog
alertDialog.Window.SetLayout(800, height);

How to merge cell in datagridview then add a combobox to cell was merged?

I have a function merge cell in datagridview in clr window form application as below:
void EquipmentDataScreen::MergeCellsInColumn(DataGridView^ datagrid,int col, int row1, int row2)
{
Graphics^ g = datagrid->CreateGraphics();
Pen^ p = gcnew Pen(datagrid->GridColor);
Rectangle r1 = datagrid->GetCellDisplayRectangle(col, row1, true);
Rectangle r2 = datagrid->GetCellDisplayRectangle(col, row2, true);
int recHeight = 0;
String^ recValue ="";
for (int i = row1; i <= row2; i++)
{
recHeight += datagrid->GetCellDisplayRectangle(col, i, true).Height;
if (datagrid->Rows[i]->Cells[col]->Value != nullptr)
recValue += datagrid->Rows[i]->Cells[col]->Value->ToString() + " ";
}
Rectangle newCell = Rectangle(r1.X, r1.Y, r1.Width-1, recHeight-1);
g->FillRectangle(gcnew SolidBrush(datagrid->DefaultCellStyle->BackColor), newCell);
g->DrawRectangle(p, newCell);
StringFormat^ strformat = gcnew StringFormat();
strformat->Alignment = StringAlignment::Center;
strformat->LineAlignment = StringAlignment::Center;
g->DrawString(recValue, datagrid->DefaultCellStyle->Font, gcnew SolidBrush(datagrid->DefaultCellStyle->ForeColor), newCell, strformat);
//g->DrawString(recValue, datagrid->DefaultCellStyle->Font, gcnew SolidBrush(datagrid->DefaultCellStyle->ForeColor), newCell.X + 3, newCell.Y + 3);
}
But this function simply draws a rectangle to cells that I want to merge.
The question is "is there a way to actually merge cell in datagridview then add combobox or text box to cell was merged?"
Please help me.
Thank you very much!

Line break in date axis with amcharts

As you can see here http://allopensensors.com/profile/andreas/
the date on x-axis is nonreadable. I'd like to add a line break. How can i solve this?
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "http://allopensensors.com/amcharts/images/";
chart.dataProvider = chartData;
chart.marginLeft = 10;
chart.categoryField = "year";
chart.dataDateFormat = "YYYY-MM-DD JJ:NN:SS";
// listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
// categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "200"; // our data is yearly, so we set minPeriod to YYYY
categoryAxis.dashLength = 3;
categoryAxis.minorGridEnabled = true;
categoryAxis.minorGridAlpha = 0.1;
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.axisAlpha = 0;
valueAxis.inside = true;
valueAxis.dashLength = 3;
chart.addValueAxis(valueAxis);
// GRAPH
graph = new AmCharts.AmGraph();
graph.type = "smoothedLine"; // this line makes the graph smoothed line.
graph.lineColor = "#d1655d";
graph.negativeLineColor = "#637bb6"; // this line makes the graph to change color when it drops below 0
graph.bullet = "round";
graph.bulletSize = 8;
graph.bulletBorderColor = "#FFFFFF";
graph.bulletBorderAlpha = 1;
graph.bulletBorderThickness = 2;
graph.lineThickness = 2;
graph.valueField = "value";
graph.balloonText = "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>";
chart.addGraph(graph);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorAlpha = 0;
chartCursor.cursorPosition = "mouse";
chartCursor.categoryBalloonDateFormat = "JJ:NN:SS";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
chart.creditsPosition = "bottom-right";
// WRITE
chart.write("chartdiv");
});
// this method is called when chart is first inited as we listen for "dataUpdated" event
function zoomChart() {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
// chart.zoomToDates(new Date(1972, 0), new Date(2200, 0));
chart.zoomToIndexes(chartData.length - 40, chartData.length - 1);
}
To make it readable, you can rotate the labels with custom angle. Try categoryAxis.labelRotation : 45
For Reference: http://www.amcharts.com/demos/column-with-rotated-series/
Hope it helps!

CreateJS - Collision detection between two createjs.Containers

I currently have this working in a desktop browser but not on touch devices because I update the variables I need on mouseover. So to get around this I am trying to check for collision detection between two containers and then update the needed variables. The items should snap to the placeholder positions when a collision between the two is detected. The catch is that items and placeholders are placed dynamically any item must be able to snap to any placeholder.
var placeholders,items,selectedItem,collision,startX, startY, snapX, snapY, xpos, ypos;
var stage = new createjs.Stage("canvas");
createjs.Touch.enable(stage);
createjs.Ticker.addEventListener("tick", tick);
function init(){
xpos = 0;
ypos = 120;
container = new createjs.Container();
stage.addChild(container);
placeholders = new createjs.Container();
placeholders.name = "placeholders"
stage.addChild(placeholders);
items = new createjs.Container();
stage.addChild(items);
for(i=0;i<2;i++){
placeholder = new CustomContainer(i, "#ff0000", 100,100);
placeholder.setBounds(0,0,100,100);
placeholder.cursor = "pointer";
placeholder.x = xpos;
placeholder.name = "placeholder"+i
container.addChild(placeholder)
xpos+= (placeholder.getBounds().width + 10);
}
xpos = 0;
for(j=0;j<2;j++){
item = new CustomContainer(j, "#0000ff", 100,100);
item.active = false;
item.setBounds(0,0,100,100);
item.name = "item"+j;
item.x = xpos;
item.y = ypos;
item.startX = xpos;
item.startY = ypos;
container.addChild(item)
item.addEventListener("mousedown", selectItem);
xpos+= (item.getBounds().width + 10);
}
stage.addChild(placeholders,items);
}
function selectItem(evt) {
selectedItem = evt.target.parent;
selectedItem.mouseEnabled = false;
evt.addEventListener("mousemove", function(ev) {
moveItem(ev);
})
evt.addEventListener("mouseup", function(ev) {
selectedItem.mouseEnabled = true;
if(collision){
//New position based on the hitTest
//selectedItem.x = ;
//selectedItem.y = ;
}else{
selectedItem.x = selectedItem.startX;
selectedItem.y = selectedItem.startY;
}
})
}
function moveItem(evt){
pt = placeholders.globalToLocal(stage.mouseX, stage.mouseY);
obj = evt.target.parent;
obj.x = pt.x - 50;
obj.y = pt.y - 50;
//selectedItem collision with placeholder
collision = obj.hitTest(pt.x,pt.y)
}
function tick(evt) {
stage.update();
}
$(document).ready(init());
I am just not getting the hitTest right. You can see the working code below.
http://jsfiddle.net/non_tech_guy/2d68W/4/
The hittest will test pixel-perfect hit. I believe you're looking for a collision test.
Try this: https://github.com/olsn/Collision-Detection-for-EaselJS

Zedgraph creating too small image

The output of my graph is really small, I can't really see the values at the x and y axis. Is there a way to change this, so the graph is bigger?
My code to output the graph is:
ZedGraphControl zc = new ZedGraphControl();
GraphPane pane = zc.GraphPane;
PointPairList list1 = new PointPairList();
LineItem curve1;
pane.Title.Text = title;
pane.XAxis.Title.Text = xAxisTitle;
pane.XAxis.Scale.Min = 0;
pane.XAxis.Scale.Max = 11;
pane.YAxis.Scale.Min = 1;
pane.YAxis.Scale.Max = 12;
pane.YAxis.Title.Text = yAXisTitle;
Int32 totalCount = ds.Tables[objectName].Rows.Count;
double[] xVals = new double[totalCount], yVals = new double[totalCount];
for (int i = 0; i < totalCount; i++)
{
xVals[i] = Convert.ToDouble(ds.Tables[objectName].Rows[i]["ntotal"]);
yVals[i] = Convert.ToDouble(ds.Tables[objectName].Rows[i]["isomonth"]);
}
list1.Add(xVals, yVals);
curve1 = pane.AddCurve("Temp curve", list1, Color.Green, SymbolType.Circle);
for (int i = 0; i < totalCount; i++)
{
TextObj t = new TextObj("Teest", curve1.Points[i].Y, curve1.Points[i].X);
t.FontSpec.Border.IsVisible = false;
pane.GraphObjList.Add(t);
}
curve1.Line.Width = 1.0F;
pane.GetImage().Save(outPutDestination, ImageFormat.Png);
pane.AxisChange();
GetImage() function gets the current size of the pane, so we just have to increase the size of the entire pane(i.e: dock & maximize the window & then use the method to get the image).
DockStyle currentStyle = zedGraphControl1.Dock;
var currentWindowState = this.WindowState;
zedGraphControl1.Dock = DockStyle.Fill;
this.WindowState = FormWindowState.Maximized;
zedGraphControl1.GetImage ().Save ( #"c:\Image_1.png" );
this.WindowState = currentWindowState;
zedGraphControl1.Dock = currentStyle;