Is anyone aware of a Winforms control for c# similar to the Tags control that stackoverflow uses (see below)?
I开发者_如何学编程f not, what are some good alternatives you've used to handle tags?
I came across your question not long ago looking for the same thing. The closest I could find was a CodeProject article on tag clouds so eventually I gave up on finding something ready out-of-the-box and made one myself. I've made a Nuget package out of it and the source is freely available on GitHub.
Source (GitHub): https://github.com/nathanchere/FerretLib.WinForms
Binary (Nuget): https://www.nuget.org/packages/FerretLib.WinForms
PS: I don't think this should be considered 'spam' since it was specifically written to address the same need as presented in this question.
Well after just a couple of minutes playing around, I have an extremely simple implementation. There's a lot more work to go into this but you can see the basic premise behind one way of accomplishing what you're after.
Form1.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;
namespace TagInput
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void TagInputContainer_Click(object sender, EventArgs e)
{
TextBox box = new TextBox()
{
Width = 100,
Height = 30,
Font = new Font("Segoe UI Light", 12),
BorderStyle = BorderStyle.None,
BackColor = Color.Khaki,
Location = new Point(0,0),
Dock = DockStyle.Left,
Margin = new Padding(2, 0, 0, 0)
};
TagInputContainer.Controls.Add(box);
}
}
}
Form1.Designer.cs:
namespace TagInput
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.TagInputContainer = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// TagInputContainer
//
this.TagInputContainer.Cursor = System.Windows.Forms.Cursors.IBeam;
this.TagInputContainer.Location = new System.Drawing.Point(157, 161);
this.TagInputContainer.Name = "TagInputContainer";
this.TagInputContainer.Size = new System.Drawing.Size(406, 30);
this.TagInputContainer.TabIndex = 0;
this.TagInputContainer.Click += new System.EventHandler(this.TagInputContainer_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(664, 395);
this.Controls.Add(this.TagInputContainer);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel TagInputContainer;
}
}
How it works:
Place a Panel on the Form, call it TagInputContainer (it will hold all the "tags"). Set the Cursor property of the Panel to IBeam
so the user knows they can type in it. When the user clicks in the TagInputContainer, create a "tag" (TextBox), set its DockStyle property to Left so that they always go to the left and so you don't have to manually handle Location foreach new "tag".
What you can do to improve it:
- Measure the Font string so that the TextBox width grows and shrinks with the text.
- Implement the backspace feature where if you press backspace up to the last tag, it will then enable editing of the tag and backspace until you stop.
- Draw an "x" on the TextBox controls or beside them so the user can click to delete them
Handle the space bar button so that when the user presses Spacebar it will create a new tag.
Another thing you could do is when the user creates a new tag, set the previous tag to Enabled = false so that it appears as though a real tag has just been created. For this effect I believe it would look better if you did not have the default system 3d box effect on the textboxes, but choose a more flat appearance, such as BorderStyle.FixedSingle or BorderStyle.None.
精彩评论