I am just creating an application in C# Windows Forms for Book Store application
The process i am doing here is
1.Inserting Book name, book image to Database.
2.Now i need to retrieve as in the image to forms but all should be dynamically created like if i have two books this panel with picture box, button and that textbook should be created and values should be showed there..
If i have got three entereids in DB means the three picture box, button and that textbook should be created and values should be showed there in the form.
is there any way to solve this out..
Need to Create these controls Dynamically according to the "n" number of rows in Database
For more Clarity about my question please see the image
Create a user control that contains the image, text box and button. Iterate over your list of records retrieved from the database and create new instance of the user control for each item. Add the user controls to the parent control's Controls collection.
You can achieve this using list view control:
you can get more details on this:
http://www.dotnetperls.com/listview
http://www.c-sharpcorner.com/UploadFile/9a3ae2/using-listview-control-windows-form-application3/
http://www.java2s.com/Code/CSharp/GUI-Windows-Form/ListViewExample.htm
I hope it will help you.,. :)
Use UserControl to build your custom control (image, text field, button) (http://msdn.microsoft.com/en-us/library/aa302342.aspx)
Use FlowLayoutPanel or TableLayoutPanel to add controls on your form.
Create Winforms project and add this file:
CtrlBuyBook.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace UserControls
{
public class CtrlBuyBook : UserControl
{
public int BookID { get; set; }
public int Quantity
{
get { return (int)nudQuantity.Value; }
set { nudQuantity.Value = value; }
}
public Image Cover
{
set { picCover.Image = value; }
}
public CtrlBuyBook()
{
InitializeComponent();
}
private void btnBuy_Click(object sender, System.EventArgs e)
{
OnBuyBook(EventArgs.Empty);
}
public event EventHandler<EventArgs> BuyBook;
private void OnBuyBook(EventArgs e)
{
var handler = BuyBook;
if (handler != null)
{
handler(this, e);
}
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.picCover = new System.Windows.Forms.PictureBox();
this.btnBuy = new System.Windows.Forms.Button();
this.nudQuantity = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.picCover)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudQuantity)).BeginInit();
this.SuspendLayout();
this.picCover.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.picCover.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picCover.Location = new System.Drawing.Point(4, 4);
this.picCover.Name = "picCover";
this.picCover.Size = new System.Drawing.Size(143, 167);
this.picCover.TabIndex = 0;
this.picCover.TabStop = false;
this.btnBuy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnBuy.Location = new System.Drawing.Point(95, 177);
this.btnBuy.Name = "btnBuy";
this.btnBuy.Size = new System.Drawing.Size(52, 20);
this.btnBuy.TabIndex = 2;
this.btnBuy.Text = "Buy";
this.btnBuy.UseVisualStyleBackColor = true;
this.btnBuy.Click += new System.EventHandler(this.btnBuy_Click);
this.nudQuantity.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.nudQuantity.Location = new System.Drawing.Point(4, 177);
this.nudQuantity.Name = "nudQuantity";
this.nudQuantity.Size = new System.Drawing.Size(85, 20);
this.nudQuantity.TabIndex = 3;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.nudQuantity);
this.Controls.Add(this.btnBuy);
this.Controls.Add(this.picCover);
this.Name = "ctrlBuyBook";
this.Size = new System.Drawing.Size(150, 200);
((System.ComponentModel.ISupportInitialize)(this.picCover)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudQuantity)).EndInit();
this.ResumeLayout(false);
}
private System.Windows.Forms.PictureBox picCover;
private System.Windows.Forms.Button btnBuy;
private System.Windows.Forms.NumericUpDown nudQuantity;
}
}
Next add FlowLayoutPanel and Button on your form.
In form code at the begining add this:
private int _bookCount = 0;
Then on button's click event add following code:
var control = new CtrlBuyBook();
control.BookID = ++_bookCount;
control.Cover = null;
control.Quantity = 1;
control.BuyBook += new EventHandler<EventArgs>(control_BuyBook);
flpPanel.Controls.Add(control);
And finally the method for user control's BuyBook event:
private void control_BuyBook(object sender, EventArgs e)
{
var control = (CtrlBuyBook)sender;
MessageBox.Show(string.Format("Customer wants to buy book with ID: {0}. Quantity: {1}", control.BookID, control.Quantity));
}
All you need is to retrieve your books from DB and display on form and handle BuyBook event from User Control.
That's all.
It's simple to achieve what you want. You just need to create some UserControl for each book or a Panel is OK. I'll introduce to using the Panel for it. Something like this:
public class BookPanel : Panel
{
public string BookName
{
get { return text.Text; }
set { text.Text = value; }
}
public Image BookCover
{
get { return pic.Image; }
set { pic.Image = value; }
}
public event EventHandler BuyBook;
public string BuyButtonText
{
get { return button.Text; }
set { button.Text = value; }
}
//inner child controls
PictureBox pic = new PictureBox();
TextBox text = new TextBox();
Button button = new Button();
public BookPanel()
{
pic.Parent = text.Parent = button.Parent = this;
pic.Top = 5;
text.Left = pic.Left = 5;
button.Text = "Buy";
button.Width = 50;
button.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
text.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right;
pic.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
pic.SizeMode = PictureBoxSizeMode.StretchImage;
button.Click += (s, e) =>
{
EventHandler handler = BuyBook;
if (handler != null) handler(this, EventArgs.Empty);
};
}
bool init;
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (!init)
{
text.Width = Width - button.Width - 12;
button.Left = text.Right + 5;
pic.Height = Height - 35;
pic.Width = Width - 10;
text.Top = pic.Bottom + 5;
button.Top = text.Top - 2;
init = true;
}
}
}
//Usage
bookPanel1.BookCover = yourImage;
//Try this to see how the Buy button works
bookPanel1.BuyBook += (s, e) => {
MessageBox.Show(bookPanel1.BookName);
};
NOTE: The code above is not complete, you don't have full ability to customize the look and feel of your TextBox, Button and PictureBox, however you can add code to do so, the code is a little much. I think for a simple control, it's enough. You should also notice the use of Dock property, the Margin and Padding properties and other layout and container controls like Panel, FlowLayoutPanel, TableLayoutPanel to customize your own control.
To use it in a FlowLayoutPanel, try this code:
flowLayoutPanel1.AutoScroll = true;
for (int i = 0; i < 100; i++) {
new BookPanel {
Parent = flowLayoutPanel1,
Width = 150,
Height = 200,
BorderStyle = BorderStyle.FixedSingle,
BookCover = yourImageList[i]
}.BuyBook += buyBook;
}
private void buyBook(object sender, EventArgs e){
BookPanel book = sender as BookPanel;
//your code goes here ....
}
Related
Hi I need to adjust the columns header such that they occupy the entire window when it is maximized.
The expected output are the listview columns ocupping the entire window but the real output are the columns don't ocuppy the entire window, otherwise the columns are ocupping a part of the window when it's maximized.
This is the class when I declare the methods are initializing and resizing the listview with their respective columns (these are not ocupping the entire window when I have it maximized.
public Takenshows()
{
InitializeComponent();
lvwColumnSorter = new ListViewColumnSorter();
this.listView1.ListViewItemSorter = lvwColumnSorter;
listView1.Dock = System.Windows.Forms.DockStyle.Fill; //The table occupies the entire width of the window when the window is maximized.
}
//this is a helper method where we REFIT the sampler table by maximizing it
private void SizeLastColumn(System.Windows.Forms.ListView lv)
{
lv.Columns[lv.Columns.Count - 1].Width = -2;
lv.Columns[lv.Columns.Count - 1].AutoResize(ColumnHeaderAutoResizeStyle.None);
lv.Dock = System.Windows.Forms.DockStyle.Fill;
lv.Alignment = ListViewAlignment.SnapToGrid;
}
//A method that allows you to wrap the table by calling the helper method that wraps the table when the window is maximized.
private void listView1_Resize(object sender, System.EventArgs e)
{
SizeLastColumn((System.Windows.Forms.ListView)sender);
}
private void Takenshows_Load(object sender, EventArgs e)
{
// INITIALIZE the table
listView1.View = View.Details;
SizeLastColumn(listView1);
}
And this is a part from the code I have the designer of Takenshows.cs with the listview and their respective columns header.
public System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ColumnHeader columnordnum;
private System.Windows.Forms.ColumnHeader columndatetimeshow;
private System.Windows.Forms.ColumnHeader columnvalues;
private System.Windows.Forms.ColumnHeader columntestnumber;
this.listView1.Alignment = System.Windows.Forms.ListViewAlignment.SnapToGrid;
this.listView1.AllowColumnReorder = true;
this.listView1.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnordnum,
this.columndatetimeshow,
this.columnvalues,
this.columntestnumber});
this.listView1.FullRowSelect = true;
this.listView1.HideSelection = false;
this.listView1.Location = new System.Drawing.Point(3, 4);
this.listView1.Margin = new System.Windows.Forms.Padding(5);
this.listView1.MultiSelect = false;
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(1064, 559);
this.listView1.AllowColumnReorder = true;
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listView1.TabIndex = 1;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
this.listView1.SelectedIndexChanged += new
System.EventHandler(this.listView1_SelectedIndexChanged);
//
// columnordnum
//
this.columnordnum.Text = "Order number";
this.columnordnum.Width = 115;
this.columnordnum.AutoResize(System.Windows.Forms.ColumnHeaderAutoResizeStyle.None);
//
// columndatetimeshow
//
this.columndatetimeshow.Text = "datetime show";
this.columndatetimeshow.Width = 140;
this.columndatetimeshow.AutoResize(System.Windows.Forms.ColumnHeaderAutoResizeStyle.None);
//
// columnvalues
//
this.columnvalues.Text = "values";
this.columnvalues.Width = 420;
this.columnvalues.AutoResize(System.Windows.Forms.ColumnHeaderAutoResizeStyle.None);
//
// columntestnumber
//
this.columntestnumber.Text = "test number";
this.columntestnumber.Width = 105;
this.columntestnumber.AutoResize(System.Windows.Forms.ColumnHeaderAutoResizeStyle.None);
I should rendering the listview such that the columns of the listview occupy the entire window when it's maximizing.
Is there any way can I solve this issue?
Your objective is to scale the ListView columns to fill the entire width of the main window when it's maximized (or generally resized). Assuming that the ListView is anchored, subscribing the the event fired by the ListView when it resizes will allow you to recalculate proportional (or custom) widths based on the new width of the window. For example:
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
autoScaleColumns();
listView.Anchor = (AnchorStyles)0xF;
listView.SizeChanged += (sender, e) => autoScaleColumns();
}
private void autoScaleColumns()
{
var proportional = listView.ClientRectangle.Width / listView.Columns.Count;
foreach (ColumnHeader column in listView.Columns)
{
column.Width = proportional;
}
}
}
I would also encourage you to look into the alternative of using DataGridView which has built-in AutoSize properties that are much more flexible.
I´m using WindowsForm and working with flat design. In the program there are 6 buttons, these buttons are made of a label and a panel. The label controls all the actions that the button can do. when i started writing the program i made one function for each button, now i like to use one function that controls all buttons. I have tried to make that work but I´m stuck and can´t find a way to solve it.
Been looking around at the forum for solutions but i think that i might not know what i´m looking for.
This is what i made so far.
Buttons[] cobra = new Buttons[5];
private class Buttons
{
private bool position;
private string name;
public bool Position
{
get { return position; }
set { position = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
private void SetButtons()
{
cobra[0].Name = "label3";
cobra[0].Position = false;
cobra[1].Name = "label4";
cobra[1].Position = false;
}
private void CheckStatusButtons(object import)
{
for (int i = 0; i < cobra.Length; i++)
{
}
}
private class ToggelFunction
{
private bool hawk;
public bool Hawk
{
get { return hawk; }
set { hawk = value; }
}
}
ToggelFunction tiger = new ToggelFunction();
private void label3_Click(object sender, EventArgs e)
{
if (tiger.Hawk == false)
{
button1.BackColor = Color.PaleGreen;
label3.Text = "ON";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 16, 1 });
}
tiger.Hawk = true;
return;
}
if (tiger.Hawk == true)
{
button1.BackColor = Color.DarkSeaGreen;
label3.Text = "2";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 8, 1 });
}
tiger.Hawk = false;
return;
}
}
"label3_Click" this is my function for button 1, all buttons look the same just different variables.
As I found on the forum, you can use object sender to i identify which button that made the click and from there use that in the function to make action.
So all buttons will use this functions, i´m not sure how to compare values in the if statement, if button 1 is click then it should check what values button 1 has.
My idea was to make a class "Buttons" and an array to store all the values of each button, it´s not completed yet. When a button is clicked it checks
with the array what values that button has and compare that in the function depending on what the action is. The first action would be to check if the button is on or off. If it´s off then it enters that if statement and there some actions will happen, change of color and the text, these values also have to be stored in the array i guess.
I have tried to compare the array with object sender, but i get some error saying that you can´t compare bool with object i think.
So i wonder if some one might have a solution or suggestions?
I have made a simple example of what i think you want to do. bare in mind this does not abide by all coding best practises but its not a mess either. You will need to put your safety null checks in.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class ButtonVariables
{
public int value1 { get; set; }
public int value2 { get; set; }
}
Dictionary<string, ButtonVariables> bv = new Dictionary<string, ButtonVariables>();
private void ProcessClick(object sender, EventArgs e)
{
ButtonVariables vars = GetVariables(sender);
//Do stuff with your variable set here
}
private ButtonVariables GetVariables(object sender)
{
ButtonVariables returnValue = new ButtonVariables();
switch (((Button)sender).Name.ToLower())
{
case "buttona":
return bv["A"];
case "buttonb":
return bv["B"];
case "buttonc":
return bv["C"];
default:
break;
}
return null;
}
private void ButtonA_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonB_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonC_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
}
I've basically added two methods to handle your method. One to identify the button and get its related values from a dictionary that you will have to populate with your Buttons class. and one to carry out the logic.
EDIT
As requested in the comments here's an easy (but not the only way) to point your event listeners towards the same method.
Initially you need to set up with one button and double click it or do some other way to create the forms Button_Click() Event Method. At this point an event listener delegate has been added to your Form.Designer.cs File. Open that file and you will see something like this:
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ButtonA_Click);
What you need to do is create your other buttons and add this code in for them with a change to the last line new System.EventHandler(this.ButtonA_Click); This line basically states which method to call when the ButtonA.Click event is invoked. At this point you can add what ever method you want (as long as you name is nicely for good convention). So your example would be this :
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonB
//
this.ButtonB.Location = new System.Drawing.Point(12, 12);
this.ButtonB.Name = "ButtonB";
this.ButtonB.Size = new System.Drawing.Size(75, 23);
this.ButtonB.TabIndex = 0;
this.ButtonB.Text = "B";
this.ButtonB.UseVisualStyleBackColor = true;
this.ButtonB.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonC
//
this.ButtonC.Location = new System.Drawing.Point(12, 12);
this.ButtonC.Name = "ButtonC";
this.ButtonC.Size = new System.Drawing.Size(75, 23);
this.ButtonC.TabIndex = 0;
this.ButtonC.Text = "C";
this.ButtonC.UseVisualStyleBackColor = true;
this.ButtonC.Click += new System.EventHandler(this.ProcessClick);
Remember you need to physically create the buttons on the form itself.
Lets say you have three labels and a panel for each label. You can add the event handler to all of them and whenever that event fires the event handler will use that label as the sender. To keep the panel associated with the label, you could add the panel to the label's tag property. Then, in the event handler you can then get the panel from the label.
label1.Click += label_Click;
label2.Click += label_Click;
label3.Click += label_Click;
label1.Tag = panel1;
label2.Tag = panel2;
label3.Tag = panel3;
In the event handler, just cast sender to Label and there you have your label object to do whatever you want with and like I said, the panel is in the Tag property. I did a little refactoring to your code to make it cleaner looking.
private void label_Click(object sender, EventArgs e)
{
// this is what itsme86 was suggesting in the comments
var label = (Label)sender;
var panel = (Panel)label.Tag;
label.BackColor = tiger.Hawk ? Color.DarkSeaGreen : Color.PaleGreen;
label.Text = tiger.Hawk ? "2" : "ON";
if (myport.IsOpen)
send(new byte[] { 16, 128, 32, 8, 1 });
tiger.Hawk = !tiger.Hawk;
}
Let me know if you have any questions about this.
I have a bounded DataGridView. How can I add a button in one field with data? I will attach a screenshot of how I see it. Do you have any recommendations on this?
it's WinForms and I think that I need to write a custom column type.
I don't think the standard DataGridViewColumn subclasses provide what you're after.
It can be done, though: you will have to create your own custom Control (I guess a TextBox with a Button right next to it), and the appropriateDataGridViewColumn and DataGridViewCell subclasses to host your custom control.
Follow the documentation for further details.
Of course, the alternative would be using third-party, smarter grids.
Create custom column:
class TextAndButtonControl : UserControl
{
private TextBox textbox1;
private Button button1;
public TextAndButtonControl()
{
this.textbox1 = new TextBox();
this.Controls.Add(this.textbox1);
this.button1 = new Button();
this.Controls.Add(this.button1);
this.RenderControl();
this.button1.Click += new EventHandler(button1_Click);
}
void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hi");
}
public string Text
{
get { return this.textbox1.Text; }
set { this.textbox1.Text = value; }
}
public string ButtonText
{
get { return this.button1.Text; }
set { this.button1.Text = value; }
}
public void RenderControl()
{
this.textbox1.Location = new Point(0, 0);
this.textbox1.Width = 2 * this.Width / 3;
this.textbox1.Height = this.Height;
this.button1.Location = new Point(2 * this.Width / 3, 0);
this.button1.Width = this.Width / 3;
this.button1.Height = this.Height;
}
}
Add the control in the following way
private void Form1_Load(object sender, EventArgs e)
{
TextAndButtonControl bcol = new TextAndButtonControl();
bcol.Text = "Button Column ";
bcol.ButtonText = "Click Me";
bcol.Name = "btnClickMe";
bcol.RenderControl();
dgMainGrid.Controls.Add(bcol);
}
There is a DataGridViewButtonColumn-Type (Or if you just want a single Cell as Button -> DataGridViewButtonCell-Type).
You could create the DataGridButtonColumn and then add it to your DataGridView:
DataGridViewButtonColumn tempBtnColumn = new DataGridViewButtonColumn();
tempBtnColumn.HeaderText = "Button";
tempBtnColumn.Text = "Button-Text";
tempBtnColumn.Name = "Button-Name";
tempBtnColumn.UseColumnTextForButtonValue = true;
Grid.Columns.Add(tempBtnColumn);
//or if you want a specified position for the Grid:
Grid.Columns.Insert(0, tempBtnColumn);
Update
Here is an update, you could give the ButtonCell the Value you want and then read that with CurrentCell.Value (here is a example, hope it's understandable):
private void ButtonCellWithValue()
{
DataGridViewButtonCell dgvbc = new DataGridViewButtonCell();
dgvbc.Value = "1";
DataGridViewRow dgvr = new DataGridViewRow();
dgvr.Cells.Add(dgvbc);
dataGridView1.Rows.Add(dgvr);
dgvbc = new DataGridViewButtonCell();
dgvbc.Value = "2";
dataGridView1.Rows[0].Cells[1] = dgvbc;
GridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
}
void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (((DataGridView)sender).CurrentCell.Value == "1")
{
MessageBox.Show("Super");
}
else if (((DataGridView)sender).CurrentCell.Value == "2")
{
MessageBox.Show("Better");
}
}
Thank a lot #RavirajPalvankar.
If somebody will need, I will write the code here, because cann't write it to Ravuraj's comment, because it's long:
Use the class as Raviraj write:
class TextAndButtonControl : UserControl
{
private TextBox textbox1;
private Button button1;
public TextAndButtonControl()
{
this.textbox1 = new TextBox();
this.Controls.Add(this.textbox1);
this.button1 = new Button();
this.Controls.Add(this.button1);
this.renderControl();
this.button1.Click += new EventHandler(button1_Click);
}
void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Click! The value is:" + this.Text);
}
public string Text
{
get { return this.textbox1.Text; }
set { this.textbox1.Text = value; }
}
public string ButtonText
{
get { return this.button1.Text; }
set { this.button1.Text = value; }
}
public void renderControl()
{
this.textbox1.Location = new Point(0, 0);
this.textbox1.Width = 2 * this.Width / 3;
this.textbox1.Height = this.Height;
this.button1.Location = new Point(2 * this.Width / 3, 0);
this.button1.Width = this.Width / 3;
this.button1.Height = this.Height;
}
}
then in main Form:
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("col1");
dt.Columns.Add("col2");
for (int j = 0; j < 20; j++)
{
dt.Rows.Add("col1" + j.ToString(), "col2" + j.ToString());
}
this.dataGridView1.DataSource = dt;
this.dataGridView1.Columns[0].Width = 150;
this.txbtnControl = new TextAndButtonControl();
this.txbtnControl.Visible = false;
this.dataGridView1.Controls.Add(this.txbtnControl);
//Handle the cellbeginEdit event to show the usercontrol in the cell while editing
this.dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
}
TextAndButtonControl txbtnControl;
void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.RowIndex != this.dataGridView1.NewRowIndex)
{
Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
this.txbtnControl.Location = rect.Location;
this.txbtnControl.Size = rect.Size;
this.txbtnControl.Text = this.dataGridView1.CurrentCell.Value.ToString();
this.txbtnControl.ButtonText = "...";
this.txbtnControl.renderControl();
this.txbtnControl.Visible = true;
}
}
I am looking to add a rightpanel menu to the Encompass application to show additional data while in a loan. I had a friend give me the following code as a starting point, but I'm getting lost (not sure if I'm missing references, etc.). I'm a pretty novice programmer looking at code from someone much much better than me. So any help in getting this to work would be appreciated!
using System;
using EllieMae.Encompass.ComponentModel;
using EllieMae.Encompass.Automation;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
namespace RightPanel
{
[Plugin]
public class RightPanel
{
private Form mainForm;
private TabControl _tabs;
private bool _created;
private Panel rightPanel;
public RightPanel()
{
EncompassApplication.Login += new EventHandler(EncompassApplication_Login);
}
private void EncompassApplication_Login(object sender, EventArgs e)
{
foreach (Form form in Application.OpenForms)
{
if (form.Text.ToLower().Contains("encompass"))
{
mainForm = form;
}
}
Control[] controlArray = mainForm.Controls.Find("tabControl", true);
if ((uint)((IEnumerable<Control>)controlArray).Count<Control>() <= 0U)
return;
_tabs = controlArray[0] as TabControl;
_tabs.SelectedIndexChanged += new EventHandler(SelectedIndex_Changed);
}
private void SelectedIndex_Changed(object sender, EventArgs e)
{
if (_tabs.SelectedIndex < 0)
return;
TabPage tabPage = _tabs.TabPages[_tabs.SelectedIndex];
if (tabPage != null && (tabPage.Name.Contains("loanTabPage")))
BindToRightPanel();
}
private void BindToRightPanel()
{
if (_created)
return;
Control[] controlArray = mainForm.Controls.Find("rightPanel", `enter code here`true);
if (((IEnumerable<Control>)controlArray).Count() > 0)
{
rightPanel = controlArray[0] as Panel;
CreateMenu();
}
}
private void CreateMenu()
{
if (mainForm == null)
return;
RemoveControlById(Settings.MainMenu, rightPanel);
RemoveControlById(Settings.MenuButtonPanel, rightPanel);
MenuButton menuButton = GetMenuButton("Open Loan Tools", "MtgMenuButton");
menuButton.BackColor = Color.White;
MenuPanel = new MenuPanel(Settings.GetMenu(), menuButton);
MenuPanel.Name = Settings.MainMenu;
MenuPanel.Dock = DockStyle.Right;
Panel panel = new Panel();
panel.Name = Settings.MenuButtonPanel;
panel.Width = 27;
panel.Dock = DockStyle.Right;
panel.Controls.Add((Control)menuButton);
rightPanel.Controls.Add((Control)MenuPanel);
rightPanel.Controls.Add((Control)panel);
_created = true;
}
private List<MenuPanelSection> GetMenu()
{
return new List<MenuPanelSection>()
{ new MenuPanelSection(Utilities.GetHeading("Loan Information"), Utilities.HighestWeightedPersona() == "Loan Officer", new Control[1]
{
(Control) new LoanInformation()
})
};
}
private void RemoveControlById(string controlID, Panel panel)
{
Control[] controlArray = panel.Controls.Find(controlID, true);
if ((uint)((IEnumerable<Control>)controlArray).Count<Control>() <= 0U)
return;
for (int i = 0; i < ((IEnumerable<Control>)controlArray).Count<Control>(); ++i)
controlArray[i].Parent.Controls.Remove(controlArray[i]);
}
private MenuButton GetMenuButton(string buttonText, string buttonName)
{
MenuButton menuButton = new MenuButton();
menuButton.AutoSize = true;
menuButton.FlatAppearance.BorderSize = 0;
menuButton.FlatStyle = 0;
menuButton.Height = 100;
menuButton.Name = buttonName;
menuButton.VerticalText = buttonText;
menuButton.Width = 27;
return menuButton;
}
}
This line of code appears a couple times in your sample above:
Control[] controlArray = mainForm.Controls.Find("rightPanel", true);
The Controls.Find function only takes one parameter, the name of the control you are looking for and it only returns that control if it is found, not an array of controls.
Changing the above line to this will correct that problem.
Control control = mainForm.Controls.Find("rightPanel");
Ellie Mae provides is own form objects and controls to be used in side the application. Remove the reference to the System.Windows.Forms and add:
using Elliemae.Encompass.Forms;
I haven't tried running the code, this is what I found looking through the sample you provided. If you have more specific errors I might be able to help you through them.
I was wondering how could I do this. I know I can use the button component but it has the little gray stuff around it when I give it a image. With image button how could I show another image for the hover effect
You want to create a button with no border but displays different images when the user hovers over it with the mouse? Here's how you can do it:
Add an ImageList control to your form at add two images, one for the button's normal appearance and one for when the mouse is hovering over.
Add your button and set the following properties:
FlatStyle = Flat
FlatAppearance.BorderColor (and maybe MouseOverBackColor & MouseDownBackColor) to your form's background color
ImageList = the ImageList you added to the form
ImageIndex to the index value of your normal image
Code the MouseHover and MouseLeave events for the button like this:
// ImageList index value for the hover image.
private void button1_MouseHover(object sender, EventArgs e) => button1.ImageIndex = 1;
// ImageList index value for the normal image.
private void button1_MouseLeave(object sender, EventArgs e) => button1.ImageIndex = 0;
I believe that will give you the visual effect you're looking for.
Small summary (Border, MouseDownBackColor, MouseOverBackColor)
FlatApperance
BorderColor = Black or what ever you want
BorderSize = can be set to 0
MouseDownBackColor = Transparent
MouseOverBackColor = Transparent
Text = none
For MouseDown:
// ImageList index value for the mouse down image.
private void button1_MouseDown(object sender, MouseEventArgs e) => button1.ImageIndex = 2;
You can assign the BackgroundImage property for the button. You can also use the OnMouseEnter and OnMouseExit events to change the background as per your request.
See BackgroundImage OnMouseEnter OnMouseLeave
I also needed an image button, but I wanted one like the ToolstripMenuButton.
With the correct borders and colors on hover.
So I made a custom control to do just that:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace LastenBoekInfrastructure.Controls.Controls
{
[DefaultEvent("Click")]
public class ImageButton : UserControl
{
public string ToolTipText
{
get { return _bButton.ToolTipText; }
set { _bButton.ToolTipText = value; }
}
public bool CheckOnClick
{
get { return _bButton.CheckOnClick; }
set { _bButton.CheckOnClick = value; }
}
public bool DoubleClickEnabled
{
get { return _bButton.DoubleClickEnabled; }
set { _bButton.DoubleClickEnabled = value; }
}
public System.Drawing.Image Image
{
get { return _bButton.Image; }
set { _bButton.Image = value; }
}
public new event EventHandler Click;
public new event EventHandler DoubleClick;
private ToolStrip _tsMain;
private ToolStripButton _bButton;
public ImageButton()
{
InitializeComponent();
}
private void InitializeComponent()
{
var resources = new ComponentResourceManager(typeof(ImageButton));
_tsMain = new ToolStrip();
_bButton = new ToolStripButton();
_tsMain.SuspendLayout();
SuspendLayout();
//
// tsMain
//
_tsMain.BackColor = System.Drawing.Color.Transparent;
_tsMain.CanOverflow = false;
_tsMain.Dock = DockStyle.Fill;
_tsMain.GripMargin = new Padding(0);
_tsMain.GripStyle = ToolStripGripStyle.Hidden;
_tsMain.Items.AddRange(new ToolStripItem[] {
_bButton});
_tsMain.Location = new System.Drawing.Point(0, 0);
_tsMain.Name = "_tsMain";
_tsMain.Size = new System.Drawing.Size(25, 25);
_tsMain.TabIndex = 0;
_tsMain.Renderer = new ImageButtonToolStripSystemRenderer();
//
// bButton
//
_bButton.DisplayStyle = ToolStripItemDisplayStyle.Image;
_bButton.Image = ((System.Drawing.Image)(resources.GetObject("_bButton.Image")));
_bButton.ImageTransparentColor = System.Drawing.Color.Magenta;
_bButton.Name = "_bButton";
_bButton.Size = new System.Drawing.Size(23, 22);
_bButton.Click += bButton_Click;
_bButton.DoubleClick += bButton_DoubleClick;
//
// ImageButton
//
Controls.Add(_tsMain);
Name = "ImageButton";
Size = new System.Drawing.Size(25, 25);
_tsMain.ResumeLayout(false);
_tsMain.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
void bButton_Click(object sender, EventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}
void bButton_DoubleClick(object sender, EventArgs e)
{
if(DoubleClick != null)
{
DoubleClick(this, e);
}
}
public class ImageButtonToolStripSystemRenderer : ToolStripSystemRenderer
{
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//base.OnRenderToolStripBorder(e);
}
}
}
}