0

我想在 C# windows 窗体中实现类似于 jQuery TagIt 的功能。这是 jQuery 的链接 - http://aehlke.github.com/tag-it/

我正在考虑为此功能创建一个用户控件。

关于如何解决这个问题的任何帮助?

4

2 回答 2

0
public class TagLayoutPanel : FlowLayoutPanel
{
    //local variables/controls
    private TextBox _entryBox;
    private Dictionary<string,string> _currentTags;

    //events
    public delegate void TagsUpdatedHandler(TagEventArgs e);
    public event TagsUpdatedHandler TagsUpdated;

    //constructor(s)
    public TagLayoutPanel()
    {
        Init();
    }

    public List<string> GetCurrentTags()
    {
        var lst = new List<string>();
        if (_currentTags != null)
            lst = _currentTags.Keys.ToList();
        return lst;
    }
    private void Init()
    {
        _currentTags = new Dictionary<string, string>();
        //Entry box
        this.Padding = new Padding(3);
        this.BackColor = Color.White;

        _entryBox = new TextBox();
        _entryBox.BackColor = Color.White;
        _entryBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
        _entryBox.KeyUp += _entryBox_KeyUp;
        this.Controls.Add(_entryBox);
    }

    private void _entryBox_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            var tag = _entryBox.Text;
            if (!string.IsNullOrEmpty(tag))
            {
                this.AddTag(tag);
                _entryBox.Text = String.Empty;
            }
        }
    }

    protected override void OnGotFocus(EventArgs e)
    {
        //Set focus to the textentry box.
        base.OnGotFocus(e);
        this._entryBox.Focus();
    }
    public void AddTag(string tag)
    {
        bool added = false;
        if (!_currentTags.ContainsKey(tag))
        {
            _currentTags.Add(tag, tag);
            added = true;
        }

        if(added)
        {
            Redraw();
            Notify();
        }
    }
    private void Notify()
    {
        if(TagsUpdated != null)
            TagsUpdated(new TagEventArgs(GetCurrentTags().ToArray()));
    }
    public void Redraw()
    {
        this.Controls.Clear();
        foreach (var tag in _currentTags.Keys)
        {
            DrawTag(tag);
        }
        AddEntry();
    }
    private void AddEntry()
    {
        this.Controls.Add(_entryBox);
        _entryBox.Focus();
    }

    public void DrawTag(string tag)
    {
        var lbl = new Label();
        lbl.MouseMove += lbl_MouseMove;
        lbl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        lbl.BackColor = Color.LightGray;
        lbl.Name = "lbl_" + tag.Replace(" ", "");
        lbl.ImageAlign = ContentAlignment.TopRight;
        lbl.Text = tag;
        lbl.Tag = tag;
        lbl.Image = Resources.close_x; //Replace with your own image.
        lbl.Click += lbl_Click;
        this.Controls.Add(lbl);
    }

    private void lbl_Click(object sender, EventArgs e)
    {
        var lbl = (Label)sender;
        bool removed = false;
        foreach(var item in this.Controls)
        {
            if(item is Label)
            {
                if(((Label)item).Tag.ToString() == lbl.Tag.ToString())
                {
                    _currentTags.Remove(lbl.Tag.ToString());
                    removed = true;
                    break;
                }
            }
        }

        if(removed)
        {
            Redraw();
            Notify();
        }
    }

    private void lbl_MouseMove(object sender, MouseEventArgs e)
    {
        var lbl = (Label)sender;

        var startImgX = lbl.Width - 20;
        var endImgY = lbl.Height - 15;

        if (e.X >= startImgX && e.Y <= endImgY)
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Hand;
        else
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Arrow;

    }
}

public class TagEventArgs : EventArgs
{
    public string[] Tags { get; private set; }
    public TagEventArgs(string[] tags)
    {
        Tags = tags;
    }
}
于 2013-12-26T18:34:21.120 回答
0

你很幸运,因为已经有一个名为 a 的容器控件FlowLayoutPanel,它将为你提供 90% 的路径作为流动标签主机。

FlowLayoutPanel 类@MSDN

此控件可从 Visual Studio 的工具箱中获得,因此一个很好的起点是创建一个基于 a 的自定义控件FlowLayoutPanel,以及另一个自定义控件来表示基于 a 的标记LabelCheckbox并更新绘图和行为(在这种情况下a Label) 响应点击并显示 [x] 以关闭标签。

标签类@MSDN
CheckBox 类@MSDN

制作完这两个控件后,您需要做一些额外的工作,以使您的 FlowLayoutPanel 派生控件添加/删除代表当前标签状态的基于标签的控件。

更新:我错过的一件事是,TextBox需要添加一个或其他输入字段以支持添加新标签。

文本框@MSDN

于 2013-02-01T00:45:16.310 回答