I have created a UserControl which has 2 properties.
See my code here:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace Controls
{
public partial class UserControl1: Panel
{
bool reset = false;
public bool _reset
{
get { return reset; }
set
{
reset = value;
if (value == true)
{
this.Controls.Clear();
cntCount = 0;
reset = false;
}
}
}
int cntCount = 0;
public int _cntCount
{
get { return cntCount; }
set
{
cntCount = value;
populate();
}
}
public UserControl1()
{
InitializeComponent();
}
void populate()
{
this.Controls.Clear();
IDesignerHost mDes = null;
mDes = (IDesignerHost)GetService(typeof(IDesignerHost));
for (int t = 0; t < cntCount; t++)
{
Button b = mDes.CreateComponent(typeof(Button), GenerateNewPaneName()) as Button;
this.Controls.Add(b);
}
}
protected string GenerateNewPaneName()
{
int curNum = 1;
bool bDuplicateName;
IReferenceService refsvc = GetService(typeof(IReferenceService)) as IReferenceService;
string curTry;
// Get a new component name
do
{
curTry = "b_" + curNum;
bDuplicateName = (refsvc.GetReference(curTry) != null);
curNum++;
}
while (bDuplicateName);
return curTry;
}
}
}
Dragging that control on the form is no problem.
If I enter a number into the property _cntCount, the control adds the required number of buttons inside my UserControl; no problem.
If I save the Form, close and reopen it, I get an error:
Duplicate component name 'b_1'. Component names must be unique and case-insensitive.
What do I miss?
Thanks in advance,
Murat
Related
I'm developing a form to my college project to show a product but when I call that form with the formName.ShowDialog() the Visual Studio trows me a OutOfMemoryException. The weird part is that I have other forms that do the same thing with more steps and none of them throws that error. The code is bellow.
This is where I call the form.
private void dtgProduzir_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32(dtgProduzir.Rows[dtgProduzir.CurrentRow.Index].Cells["clIdProducao"].Value);
ExibicaoProducao fepc = new ExibicaoProducao();
fepc.IdProducao = id;
fepc.ShowDialog();
CarregarGrids();
}
This is the form class:
using ERP_Serralheria.Dal;
using ERP_Serralheria.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ERP_Serralheria.Desktop_Chapa
{
public partial class ExibicaoProducao : Form
{
public ExibicaoProducao()
{
InitializeComponent();
}
public int IdProducao = 0;
private void ExibicaoProducao_Load(object sender, EventArgs e)
{
try
{
if (IdProducao == 0)
{
//Cadastro de produção
}
else
{
//Vizualização de uma produção
ProducaoChapa pc = new ProducaoChapa();
ProducaoChapaDal pcdal = new ProducaoChapaDal();
pc = pcdal.RetornaProducaoChapa(IdProducao);
lblIdProducao.Text = pc.Id.ToString();
lblIdVenda.Text = pc.Venda.Id.ToString();
cmbPatio.SelectedValue = pc.Patio.Id;
txtProdutor.Text = pc.Produtor.Nome;
txtVendedor.Text = pc.Venda.Usuario.Nome;
txtValor.Text = pc.ValorVenda.ToString();
txtPeso.Text = pc.Peso.ToString();
txtQuantidade.Text = pc.Quantidade.ToString();
txtLargura.Text = pc.Largura.ToString();
txtAltura.Text = pc.Altura.ToString();
txtObservacao.Text = pc.Observacao;
dtEntrega.Value = pc.Venda.DataEntrega;
if (pc.DataProducao.Year > 2019)
dtProducao.Value = pc.DataProducao;
cmbUrgencia.SelectedIndex = pc.Urgencia - 1;
//Carregar a imagem
txtIdChapa.Text = pc.Chapa.Id.ToString();
txtNomeCHapa.Text = pc.Chapa.Descricao;
pctImagem.BackgroundImage = pc.Chapa.Imagem;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Hi I'm practicing using winform MVP pattern in C#.
I made Models, Presenters and Views folders, and they has a each class.
(Models has Data.cs, Presenters has Datapresenter.cs and View have interface.cs and Form.cs)
I used 'FlowLayoutPanel'. and I made Label to make numbers. Like this.
My progress so far.
Here is Data.cs (Model)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LayoutSample.Models
{
public class Data
{
public string label { get; set; }
public string CalculateArea()
{
return label;
}
}
}
Here is DataPresenter.cs (Presenter)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using LayoutSample.Models;
using LayoutSample.Views;
namespace LayoutSample.Presenters
{
public class DataPresenter
{
IFlowLabel LabelView;
public DataPresenter(IFlowLabel view)
{
LabelView = view;
}
public void CalculateArea()
{
Data data = new Models.Data();
data.label = string.Copy(LabelView.label);
var th = new Thread(() =>
{
for (int i = 0; i < 100; i++)
{
Label label = new Label();
Panel flowLayoutPanel1 = new Panel();
label.Text = i.ToString();
flowLayoutPanel1.Controls.Add(label);
Thread.Sleep(10);
}
});
th.Start();
}
}
}
Here is interface.cs(View)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LayoutSample.Views
{
public interface IFlowLabel
{
string label { get; set; }
}
}
and this is Form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LayoutSample.Models;
using LayoutSample.Presenters;
using LayoutSample.Views;
namespace LayoutSample
{
public partial class Form1 : Form, IFlowLabel
{
public Form1()
{
InitializeComponent();
}
string IFlowLabel.label
{
get
{
return flowLayoutPanel1.ToString();
}
set
{
if (flowLayoutPanel1.InvokeRequired)
{
flowLayoutPanel1.Invoke(new MethodInvoker(() =>
{
flowLayoutPanel1.Text = value;
}));
}
else
{
flowLayoutPanel1.Text = value;
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
Label label = new Label();
label.AutoSize = false;
label.Width = 50;
label.Text = i.ToString();
flowLayoutPanel1.Controls.Add(label);
}
DataPresenter presenter = new DataPresenter(this);
presenter.CalculateArea();
}
}
}
From here, I want to make the numbers increasing.
How could I increase them at same time?
p.s
I've changed DataPresenter.cs
I've chagned public void Calculate Area() to
public void CalculateArea()
{
Data data = new Models.Data();
data.label = string.Copy(LabelView.label);
var th = new Thread(() =>
{
for ( int i = 1; i < 101; i++)
{
for (int j=1; j<101;j++)
{
Label label = new Label();
label.Text = j.ToString();
Console.WriteLine(label);
}
Thread.Sleep(1000);
}
});
th.Start();
}
I can watch the numbers increasing via console, but I can't see the change in WimForm. How can I bring the increment to WinForm??
I have two forms in WFA C#.
FORM1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication8
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
if (checkBox1.Checked == true)
{
f2.intr = checkBox1.Text;
}
if (checkBox2.Checked == true)
{
f2.intr2 = checkBox2.Text;
}
if (checkBox3.Checked == true)
{
f2.intr3 = checkBox3.Text;
}
if (checkBox4.Checked == true)
{
f2.intr4 = checkBox4.Text;
}
if (checkBox5.Checked == true)
{
f2.intr5 = checkBox5.Text;
}
f2.ShowDialog();
}
}
}
FORM2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication8
{
public partial class Form2 : Form
{
public string gen, intr, intr2, intr3, intr4, intr5;
public string interest
{
get { return intr; }
set { intr = value; }
}
public string interest2
{
get { return intr2; }
set { intr2 = value; }
}
public string interest3
{
get { return intr3; }
set { intr3 = value; }
}
public string interest4
{
get { return intr4; }
set { intr4 = value; }
}
public string interest5
{
get { return intr5; }
set { intr5 = value; }
}
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
label1.Text = "Interests: " + interest + "\n" + interest2 + "\n" + interest3 + "\n" + interest4 + "\n" + interest5;
}
}
}
I have 5 checkboxes inside a groupbox. This outputs the selected items to label1. The output looks like this when I check all the checkboxes:
art
science
math
history
sports
and whenever I check boxes randomly for example i'll check the art and history. The output is like this:
art
history
it leaves two spaces.
In the design of form1 there are the checkbox1,checkbox2,checkbox3,checkbox4,checkbox5 inside a groupbox.
In the design of form2 there is only label1.
How can I separate the selected items by a comma in one line?
I'm new to c# helpp.
You could put all the interests in an array:
string[] interests = { interest, interest2, interest3, interest4, interest5 };
Then you could remove the non-selected ones:
string[] selectedInterests = interests.Where(str => !String.IsNullOrEmpty(str)).ToArray();
At the end you can join them into a single string:
label1.Text = String.Join(", ", selectedInterests);
I have built a treeListView:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TreeListViewTest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.treeListView1.CanExpandGetter = delegate(object x)
{
return true;
};
this.treeListView1.ChildrenGetter = delegate(object x)
{
Contract contract = x as Contract;
return contrat.Children;
};
column1.AspectGetter = delegate(object x)
{
if(x is Contract)
{
return ((Contract)x).Name;
}
else
{
return " ";
}
};
column2.AspectGetter = delegate(object x)
{
if(x is Contract)
{
return ((Contract)x).Value;
}
else
{
Double d = (Double)x;
return d.ToString();
}
};
this.treeListView1.AddObject(new Contract("A", 1));
}
private void treeListView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
public class Contract
{
public string Name { get; set;}
public Double Value { get; set; }
public List<Double> Children {get; set;}
public Contract(string name, Double value)
{
Name = name;
Value = value;
Children = new List<Double>();
Children.Add(2);
Children.Add(3);
}
}
}
It gives this output:
Name Value
A 1
2
3
How do I update the values of column2 ("Value") of the parent and the children from within an event? (increasing each value by of the parent and the children.)
private void button1_Click(object sender, EventArgs e)
{
}
I do not understand if I have to use the AspectGetter again or can i modify just the values in column2 somehow and then refreshObjects().
I do not understand if I have to use the AspectGetter again or can i modify just the values in column2 somehow and then refreshObjects().
No, you should just manipulate the underlying model object and call treeListView1.RefreshObject(myObject); for example, where myObject should be a Contract in you case. This will refresh the contents of the respective rows.
I don't know what your button1_Click() is supposed to do, but you obviously require a reference of the object you want to refresh. This could be the currently selected object for example (treeListView.SelectedObject). If you tell what you want to do, I may be able to give you more information.
I'm creating an add in for Microsoft Excel that includes a ribbon tab. On this tab is a button with the following code:
public void setAccounts()
{
foreach (Excel.Worksheet displayWorksheet in Globals.ThisAddIn.Application.Worksheets)
{
displayWorksheet.Range[budget_cell].Value2 = "$" + Convert.ToString(budget);
displayWorksheet.Range[account_cell].Value2 = "$0.00";
displayWorksheet.Range[transaction_cell].Value2 = "Amount";
}
}
The button opens up a separate form where the user specifies budget_cell, account_cell, and transaction_cell. I then pass that data to the above code in SolutionName.ThisAddIn.cs (where SolutionName is the namespace of the solution). Strictly speaking, the code works. However, the data doesn't show up in the cells until the button is pressed a second time. Why is that? Is it because I'm retrieving the data from a different object in the solution?
Also, I've been trying to get this code and the aforementioned form to activate when the add in first starts up.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
frmStartup startup = new frmStartup();
startup.Show();
setAccounts();
}
I've been at this for a good twelve hours now, and I can't get it to work. What am I missing?
ThisAddIn.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
namespace AccountingAddIn
{
public partial class ThisAddIn
{
public static string budget_cell = "";
public static string account_cell = "";
public static string transaction_cell = "";
public static string date_cell = "";
public static string time_cell = "";
public static string description_cell = "";
public static bool date = false;
public static bool time = false;
public static bool description = false;
public static decimal budget = 0;
List<Account> accounts = new List<Account>();
public void budgetStartUp()
{
frmStartup startup = new frmStartup();
startup.Show();
setAccounts();
}
public void setAccounts()
{
foreach (Excel.Worksheet displayWorksheet in Globals.ThisAddIn.Application.Worksheets)
{
displayWorksheet.Range[budget_cell].Value2 = "$" + Convert.ToString(budget);
displayWorksheet.Range[account_cell].Value2 = "$0.00";
displayWorksheet.Range[transaction_cell].Value2 = "Amount";
if (date == true)
{
displayWorksheet.Range[date_cell].Value2 = "Date";
}
if (time == true)
{
displayWorksheet.Range[time_cell].Value2 = "Time";
}
if (description == true)
{
displayWorksheet.Range[description_cell].Value2 = "Description";
}
Account na = new Account(0, displayWorksheet);
accounts.Add(na);
}
}
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return Globals.Factory.GetRibbonFactory().CreateRibbonManager(
new Microsoft.Office.Tools.Ribbon.IRibbonExtension[] { new MyRibbon() });
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
CreateRibbonExtensibilityObject();
budgetStartUp();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
}
}
frmStartup.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace AccountingAddIn
{
public partial class frmStartup : Form
{
public frmStartup()
{
InitializeComponent();
}
private void btnHelp_Click(object sender, EventArgs e)
{
MessageBox.Show("Please enter a starting amount for your budget and " +
"which cells will display the running total for your " +
"accounts." +
"\n\nNote: Leaving the budget blank will" +
" result in a starting budget of $0.00.");
}
private void btnOkay_Click(object sender, EventArgs e)
{
AccountingSeminar.ThisAddIn.budget += Convert.ToDecimal(txtStartingAmount.Text);
AccountingSeminar.ThisAddIn.budget_cell = txtBudget.Text;
AccountingSeminar.ThisAddIn.account_cell = txtAccount.Text;
AccountingSeminar.ThisAddIn.transaction_cell = txtTransaction.Text;
if (chkDate.Checked)
{
AccountingSeminar.ThisAddIn.date_cell = txtDate.Text;
AccountingSeminar.ThisAddIn.date = true;
}
if (chkTime.Checked)
{
AccountingSeminar.ThisAddIn.time_cell = txtTime.Text;
AccountingSeminar.ThisAddIn.time = true;
}
if (chkDescription.Checked)
{
AccountingSeminar.ThisAddIn.description_cell = txtDescription.Text;
AccountingSeminar.ThisAddIn.description = true;
}
Close();
}
}
}