FlowLayoutPanel VerticalScroll how to use? - c#

My question refers to the previous one:
a link
I want to add the scrolling option to the FlowLayautPanel control, but I don't know how to associate adding a new row with UserControl, with VerticalScroll so that after moving it there will be visible rows that are not visible.
Below I have tried on my own to add the option of scrolling, but the content of FlowLayaoutControl shifts slower than owl, and when it reaches the end, you can not see the last lines.
public partial class ImportManager : Form
{
public ImportManager()
{
InitializeComponent();
this.flowLayoutPanel1.VerticalScroll.Visible = true;
this.flowLayoutPanel1.VerticalScroll.Maximum = 100;
}
private void DodajWierszButton_Click(object sender, EventArgs e)
{
this.flowLayoutPanel1.Controls.Add(new importRow());
this.flowLayoutPanel1.VerticalScroll.LargeChange -= 1;
}
}
I would add that I am a beginner in window programming and the solution is probably trivial, but I am not able to solve it at the moment.
I would like the FlowLayoutPanel to be able to send lines.

Related

C#, BindingNavigator, SplitButton, Ugly dot remaining

Draw a toolstrip on an empty form. Add a SplitButton on this toolstrip. Will be working as a login in button later on.
On this SplitButton I want to remove the dropdown in the start position. The only thing you can do is to login. Once you have logged in, the dropdown is populated with items like "Change Password", "Update Profile" and so on.
I have tried put the property:
loginButton.DropDownButtonWidth = 0;
this almost removes the drop down, it is gone, but its a very ugly dot on the right, which seems like to be one pixel left from the drop down corner. See images below:
I have tried a lot of other properties to remove the drop down, but no progress. And I cant find anything similar when I google.
I got excellent help fix another problem with the tool strip a few days back, the tool strip had a drawing problem too in its default state. but is removed if you do override a method, see this post:
Toolstrip drawing problem
Does anyone know how I can remove the ugly dot, or remove the drop down some other way?
Full source, one line essentially with the SplitButton named loginButton:
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
loginButton.DropDownButtonWidth = 0;
}
}
}
You can use your own renderer to try to achieve that:
private class NoArrowRenderer : ToolStripProfessionalRenderer {
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e) {
if (e.Item.GetType() != typeof(ToolStripSplitButton)) {
base.OnRenderArrow(e);
}
}
}
Then apply it to your ToolStrip:
toolStrip1.Renderer = new NoArrowRenderer();

Winforms Control

I have a button which I use all the time as a little pick button next to a combobox. When I click the button I open a larger full list. This side of things work well and I do not have a problem with this..
My problem lies when someone said to me can you change that ugly icon you picked to my nice icon.
I went crap, I have hundreds of these buttons on many forms. So I thought I will create a custom control called PickButton (which is a standard button and heap of default proeprties set) and drop these on the form everywhere instead. In the code of the PickButton custom control I set some properties and the image to the customers nice icon.
So I drop the PickButton from my toolbox onto the form, so far things are looking pretty good and I am feeling a bit clever. Now I think to myself I will change back to my nice icon not the crappy one the customer picked and change the code in the PickButton custom control. But I cannot get rid of that customers icon, because the code when the PickButton run happens before the code in the designer file which has the customers icon.
So my aim was to have a PickButton control and be able to change the icon and other properties in one place and all the properties would be set when an instance of the control is created and displayed on the form.
Was I not so clever and went about achieving the task the wrong way???
This is my PickButton custom control class
public class PickButton : Button
{
public PickButton()
{
InitialiseButton();
}
internal void InitialiseButton()
{
this.ImageAlign = ContentAlignment.MiddleCenter;
this.Image = WindowsFormsApplication1.Properties.Resources.Cancel.ToBitmap();
this.Size = new Size( 28, 28 );
this.Dock = DockStyle.Fill;
this.Margin = new Padding( 0, 2, 2, 0 );
this.Text = string.Empty;
}
}
Now I drop one onto my form and the code in the designer is as follows
//
// pickButton1
//
this.pickButton1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pickButton1.Image = ((System.Drawing.Image)(resources.GetObject("pickButton1.Image")));
this.pickButton1.Location = new System.Drawing.Point(0, 0);
this.pickButton1.Margin = new System.Windows.Forms.Padding(0, 2, 2, 0);
this.pickButton1.Name = "pickButton1";
this.pickButton1.Size = new System.Drawing.Size(284, 262);
this.pickButton1.TabIndex = 0;
this.pickButton1.Text = "pickButton1";
this.pickButton1.UseVisualStyleBackColor = true;
Now I want to change the image so I change my PickButton code to use a different icon
this.Image = WindowsFormsApplication1.Properties.Resources.Browse.ToBitmap();
Run the application andd the first icon is still the one being displayed because of this line of code in the designer file
this.pickButton1.Image = ((System.Drawing.Image)(resources.GetObject("pickButton1.Image")));
The concept of setting all the properties in one place was a good idea, it just wasn't implemented quite right. I would make this class inherit from UserControl instead of from Button. By making it a UserControl, you can use the designer to set all the properties you want, like the default Image for the button. Set that in the designer, then just drag and drop your UserControl from the toolbox onto your forms. If you are only using your "PickButton" control with comboboxes, I would put the combobox on the UserControl as well. If you ever want to change your button image in the future (or any other property for that matter), you will be able to change it in ctlPickButton and that will propogate the changes to all the instances used throughout your project(s).
ctlPickButton:
public partial class ctlPickButton : UserControl
{
public event EventHandler pickButtonClicked;
public ctlPickButton()
{
InitializeComponent();
}
//Allows buttons image to be set in code if necessary
public Image Image
{
get
{
return button1.Image;
}
set
{
if (Image != null)
{
button1.Image = value;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
if (pickButtonClicked != null)
{
pickButtonClicked(sender, e);
}
}
}
Demo Form:
public Form1()
{
InitializeComponent();
ctlPickButton1.pickButtonClicked += new EventHandler(ctlPickButton1_pickButtonClicked);
ctlPickButton2.pickButtonClicked += new EventHandler(ctlPickButton2_pickButtonClicked);
}
void ctlPickButton2_pickButtonClicked(object sender, EventArgs e)
{
if (comboBox2.SelectedItem != null)
{
MessageBox.Show(comboBox2.SelectedItem.ToString());
}
}
void ctlPickButton1_pickButtonClicked(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
MessageBox.Show(comboBox1.SelectedItem.ToString());
}
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("French");
comboBox1.Items.Add("Spanish");
comboBox1.Items.Add("English");
comboBox1.Items.Add("German");
comboBox2.Items.Add("Pizza");
comboBox2.Items.Add("Hamburger");
comboBox2.Items.Add("Potato");
comboBox2.Items.Add("Chicken");
//Shows how the default image set in the designer can be overwritten for a
//specific instance using the "Image" property
ctlPickButton2.Image = Testbed.Properties.Resources.searchIcon2;
}
}
Image of ctlPickButton in designer
I think I've found a simple, clean solution:
In the CustomButton class (which inherits from System.Windows.Forms.Button), override the Refresh() method, and set the image of the button to the one you want to see:
public class CustomButton : Button
{
public override void Refresh()
{
Image = MyResources.HappyFace;
}
}
In the form that will hold an instance of your CustomButton, simply call customButton.Refresh() in the constructor, after InitializeComponent():
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
customButton.Refresh();
}
}
I've put a demo application up on Github.

Implement a "click-here-to-expand" container

I have no better way of explaining it, but I want to implement a container that only is shown after the user clicked "Advanced" or a plus sign somewhere in the dialog. I have a login form and want to add some "Advanced" settings. But they should normally out of view.
Of course, the dialog has to resize nicely to hold the extended content.
How should I go to implement such a thing. I have tried some Google searches, but can't find the right search words. Windows doesn't seem to have it by default.
as John Willemse suggested, I ended up creating the functionality myself. I added a Panel in the form that I just set visible or invisible.
In the Form's constructor (to hide it on first view):
public FrmLogin() {
InitializeComponent();
pnlAdvanced.Visible = false;
Height -= pnlAdvanced.Height;
}
Then, I added a LinkLabel with this Clicked handler:
private void linkLabel1_LinkClicked(object sender,
LinkLabelLinkClickedEventArgs e) {
if (pnlAdvanced.Visible == false) {
Height += pnlAdvanced.Height;
pnlAdvanced.Visible = true;
} else {
Height -= pnlAdvanced.Height;
pnlAdvanced.Visible = false;
}
}
Works perfectly and no extra code needed.

How do I create a custom C# control that has some common functionality?

I am very new to C# programming. I come from autoit, and other scripting languages, the transition has been most difficult. Anyway I am working on a control in a windows form, basically I want it to be a LinkLabel control, that when you click it, it will become a textbox, once you enter your name, and either hit enter, or tab, it will set your name as the linklabel. But, I will have 10 of these controls on a form, and the way I have done it, it has taken three methods per control, so that is a lot of code, I'm sure I'm just doing it wrong, but here is what i have:
namespace Program
{
public partial class formMain : Form
{
public formMain()
{
InitializeComponent();
}
private void linkLabelPlayerName1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.linkLabelPlayerName1.Hide();
this.textBoxPlayerName1.Show();
this.textBoxPlayerName1.Focus();
this.textBoxPlayerName1.KeyPress += new KeyPressEventHandler(textBoxPlayerName1_KeyPress);
this.textBoxPlayerName1.LostFocus += new EventHandler(textBoxPlayerName1_LostFocus);
}
private void textBoxPlayerName1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
this.linkLabelPlayerName1.Text = this.textBoxPlayerName1.Text;
this.textBoxPlayerName1.Hide();
this.linkLabelPlayerName1.Show();
}
}
private void textBoxPlayerName1_LostFocus(object sender, EventArgs e)
{
this.linkLabelPlayerName1.Text = this.textBoxPlayerName1.Text;
this.textBoxPlayerName1.Hide();
this.linkLabelPlayerName1.Show();
}
}
}
I'm sure there is a way to use the last two methods between all 10 controls, so they don't have to be rewritten for each control. That is, textBoxPlayerName1_LostFocus() and textBoxPlayerName2_LostFocus().
Welcome to object orientated programming :).
You should created a derived class to encapsulate the functionality. For example:
class EditableText : UserControl
{
private LinkLabel lblName;
private TextBox txtName;
public EditableText()
{
// Construct objects, attach events and add them
// as children to this object
}
// Return the text of encapsulated TextBox
public string Text
{
get { return txtName.Text; }
}
}
Now you are able re-use this class in different areas, that's what object orientated programing all about!
Right-click on the windows forms application in the Solution Exporer, and select Add, then User Control...
Type in a name for the new control, like LinkLabelTextBox
This will give you a space to work in that looks like a Form, but without borders. This is your new control. Put your LinkLable and TextBox on this new control exactly as you put them in the window, and give them the functionality that you want. Then replace all your existing controls with instances of this new control. You will create 10 of these, instead of creating ten LinkLabels and ten TextBoxes. And all of the functionality that you want will be built-in to your new control, so that code does not need to be repeated.
Instead of a linkLabelPlayerName1 and textBoxPlayerName1, you will have a linkLabelTextBoxPlayerName1, and none of the Show, Hide, Focus stuff will clutter your form code.
Also, be sure to include a public Text property so you can get the value that the user typed out of this control.
Create your own Control with the functionality.
Your code is correct.
To make it cleaner, you should move it to a separate UserControl, and set the Text property to the textbox's value.

Cannot get Textboxes in dynamically added usercontrol to maintain state

I have tried what seems like everything - I've done similiar things many times before, but I'm obviously missing something.
I have a UserControl (ucA) - on ucA is a LinkButton that loads a different UserControl (ucB) programatically into a panel on ucA. ucB has TextBoxes, etc.
Why isn't my control maintaining it's state? ie: The textboxes are loosing thier value on postback - the control tree shows the name of the control and the Form values show the value (in trace.axd)
Here is the code for ucA (basically)
public int SlideCount
{
get { return Convert.ToInt32(ViewState["SlideCount"]); }
set { ViewState["SlideCount"] = value; }
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
SlideCount += 1;
LoadSlideControls();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
LoadSlideControls();
}
private void LoadSlideControls()
{
this.pnlAnnouncementHolder.Controls.Clear();
for (int i = 0; i < SlideCount; i++)
{
this.pnlAnnouncementHolder.Controls.Add(
LoadControl("AnnouncementSlide.ascx"));
}
}
Heres a full example of what im trying to do:
http://keithsblogs.com/ControlTest2.zip
The problem Vyrotek points out is that the control is added a little to late to the lifecycle on the click event - anyone have any ideas?
I just tried to recreate what you have setup and I dont seem to experience the same problem. Would you like me to send you my Solution somehow?
Final Edit, I promised -
Try this solution: http://www.vyrotek.com/code/ControlTest2.zip
I am installing express edition as I type. By that time, why should you clear the controls on click of the button? cant you just add/load the uc once control on click of the link?
By doing this, you would not be clearing the old controls and they would retain the value.

Categories

Resources