Управление тегами, как stackoverflow's - PullRequest
11 голосов
/ 15 июня 2011

Кто-нибудь знает об элементе управления Winforms для c #, похожем на элемент управления Tags, который использует stackoverflow (см. Ниже)?tag control example

Если нет, то какие хорошие альтернативы вы использовали для обработки тегов?

Ответы [ 2 ]

16 голосов
/ 27 февраля 2014

Я недавно сталкивался с вашим вопросом, ища то же самое.Самой близкой, которую я смог найти, была статья CodeProject о облаках тегов, так что в конце концов я разочаровался в поиске чего-то готового из коробки и сделал его сам.Я сделал из него пакет Nuget, и источник свободно доступен на GitHub.

Источник (GitHub): https://github.com/nathanchere/FerretLib.WinForms

Binary (Nuget): https://www.nuget.org/packages/FerretLib.WinForms

PS: я не думаю, что это следует рассматривать как «спам», поскольку оно было специально написано для удовлетворения той же потребности, что и представленная в этом вопросе..

7 голосов
/ 11 октября 2013

Ну, после всего лишь нескольких минут игры, у меня очень простая реализация. Для этого нужно проделать гораздо больше работы, но вы можете увидеть основную предпосылку одного способа достижения того, чего вы хотите.

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;
    }
}

Как это работает:

Поместите панель в форму, назовите ее TagInputContainer (она будет содержать все «теги»). Установите для свойства Cursor панели значение IBeam, чтобы пользователь знал, что он может его ввести. Когда пользователь щелкает в TagInputContainer, создайте «тег» (TextBox), установите его свойство DockStyle в значение Left, чтобы они всегда шли влево, и вам не нужно вручную обрабатывать Location для каждого нового «тега».

Что вы можете сделать, чтобы улучшить его:

  • Измерьте строку Font, чтобы ширина TextBox увеличивалась и уменьшалась вместе с текстом.
  • Реализовать функцию возврата на одну позицию, при которой, если вы нажмете клавишу возврата до последнего тега, он включит редактирование тега и возврата, пока вы не остановитесь.
  • Нарисуйте «x» на элементах управления TextBox или рядом с ними, чтобы пользователь мог щелкнуть, чтобы удалить их
  • Обрабатывать кнопку панели пробел , чтобы при нажатии пробела пользователь создавал новый тег.

  • Еще одна вещь, которую вы можете сделать, когда пользователь создает новый тег, установите предыдущий тег на Enabled = false, чтобы он выглядел так, как будто настоящий тег был только что создан. Я полагаю, что для этого эффекта было бы лучше, если бы у вас не было эффекта системного трехмерного блока по умолчанию для текстовых полей, но вы выбрали более плоский вид, например BorderStyle.FixedSingle или BorderStyle.None.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...