草庐IT

c# - 子字符串上的 ComboBox 自动完成

coder 2024-05-23 原文

在我的一个 WinForms 应用程序中,我有一个带有组合框的窗口,供用户从中选择客户。

此列表框中的客户采用以下格式:“CustomerID - CustomerName”,例如“004540 - NorthWind Traders”

native WinForms 组合框具有内置的自动完成功能并且运行良好:问题是它只能通过从组合框列表的每个项目的字符串开头进行匹配而不是从任何地方(子字符串)开始进行匹配。

我希望我的用户能够做的是键入 CustomerID 或 CustomerName,因为高级用户熟悉大多数 CustomerID,而新员工将受益于能够键入 CustomerName 并获得自动完成功能. 这意味着我实际上想从列表中寻找最佳匹配,其中输入的文本是 ComboBox 项的子字符串。

通常针对这种情况建议的解决方案是创建一个仅在用户键入时才显示的隐藏列表框,但我对此并不满意,因为它感觉像是一种快速破解并且不容易重用,并且与标准 ComboBox 控件相比,外观和行为可能不一致。

我尝试使用 DroppedDown 属性自己实现此功能以显示列表并使用 SelectedIndex 设置项目,但是当我这样做时组合框的文本框的内容被重置,而我只想要“最佳匹配” item”从 ComboBox 列表中突出显示(我需要“建议”而不是“追加”,追加模式无论如何不能真正用于子字符串匹配)。

我想一定有更好的方法吧? 如果有人知道自定义/第 3 方控件这样做,我也不反对购买。

谢谢。

PS:我正在使用 .Net Framework 3.5 使用 C# 为 WinForms 编程。

最佳答案

这是 C# 版本。它有很多选项。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.Load += new EventHandler(this.Form1_Load);

            InitializeComponent();
        }

    private clsCustomAutoCompleteTextbox ClsCustomAutoCompleteTextbox1 = null;

    private List<string> MasterList = new List<string> ();

    public void Form1_Load(object sender, System.EventArgs e) {
        this.ClsCustomAutoCompleteTextbox1 = new clsCustomAutoCompleteTextbox();

        this.ClsCustomAutoCompleteTextbox1.AutoCompleteFormBorder = System.Windows.Forms.FormBorderStyle.None;

        this.ClsCustomAutoCompleteTextbox1.AutoCompleteList = null;
        this.ClsCustomAutoCompleteTextbox1.Location = new System.Drawing.Point(27, 57);
        this.ClsCustomAutoCompleteTextbox1.Name = "clsCustomAutoCompleteTextbox1";
        this.ClsCustomAutoCompleteTextbox1.OnEnterSelect = true;
        this.ClsCustomAutoCompleteTextbox1.SelectionMethods = clsCustomAutoCompleteTextbox.SelectOptions.OnEnterSingleClick;
        this.ClsCustomAutoCompleteTextbox1.SelectTextAfterItemSelect = true;
        this.ClsCustomAutoCompleteTextbox1.ShowAutoCompleteOnFocus = false;
        this.ClsCustomAutoCompleteTextbox1.Size = new System.Drawing.Size(232, 20);
        this.ClsCustomAutoCompleteTextbox1.TabIndex = 0;

        this.Controls.Add(this.ClsCustomAutoCompleteTextbox1);

        this.ClsCustomAutoCompleteTextbox1.BeforeDisplayingAutoComplete +=
            new EventHandler<clsCustomAutoCompleteTextbox.clsAutoCompleteEventArgs>(BeforeDisplayingAutoComplete);

        List<string> L;
        L = new List<string>();
        L.Add("123123 - Bob");
        L.Add("534543 - Sally");
        L.Add("123123 - George");
        L.Add("34213 - Happy");
        MasterList = L;
        this.ClsCustomAutoCompleteTextbox1.AutoCompleteList = L;
    }

    private void BeforeDisplayingAutoComplete(object sender, clsCustomAutoCompleteTextbox.clsAutoCompleteEventArgs e) {
        string Name = this.ClsCustomAutoCompleteTextbox1.Text.ToLower();
        List<string> Display = new List<string> ();
        foreach (string Str in MasterList) {
            if ((Str.ToLower().IndexOf(Name) > -1)) {
                Display.Add(Str);
            }
        }
        e.AutoCompleteList = Display;
        e.SelectedIndex = 0;
    }
}
public class clsCustomAutoCompleteTextbox : TextBox
{
    private bool First = true;

    private object sender;

    private clsAutoCompleteEventArgs e;

    public List<string> test = new List<string> ();

    public int Tabs = 0;

    private int mSelStart;

    private int mSelLength;

    private List<string> myAutoCompleteList = new List<string> ();

    private ListBox myLbox = new ListBox();

    private Form myForm = new Form();

    private Form myParentForm;

    private bool DontHide = false;

    private bool SuspendFocus = false;

    private clsAutoCompleteEventArgs Args;

    private Timer HideTimer = new Timer();

    private Timer FocusTimer = new Timer();

    private bool myShowAutoCompleteOnFocus;

    private System.Windows.Forms.FormBorderStyle myAutoCompleteFormBorder = FormBorderStyle.None;

    private bool myOnEnterSelect;

    private int LastItem;

    private SelectOptions mySelectionMethods = (SelectOptions.OnDoubleClick | SelectOptions.OnEnterPress);

    private bool mySelectTextAfterItemSelect = true;

    private List<string> value;

    private int Cnt = 0;

    public bool SelectTextAfterItemSelect
    {
        get
        {
            return mySelectTextAfterItemSelect;
        }
        set
        {
            mySelectTextAfterItemSelect = value;
        }
    }

    [System.ComponentModel.Browsable(false)]
    public SelectOptions SelectionMethods
    {
        get
        {
            return mySelectionMethods;
        }
        set
        {
            mySelectionMethods = value;
        }
    }

    public bool OnEnterSelect
    {
        get
        {
            return myOnEnterSelect;
        }
        set
        {
            myOnEnterSelect = value;
        }
    }

    public System.Windows.Forms.FormBorderStyle AutoCompleteFormBorder
    {
        get
        {
            return myAutoCompleteFormBorder;
        }
        set
        {
            myAutoCompleteFormBorder = value;
        }
    }

    public bool ShowAutoCompleteOnFocus
    {
        get
        {
            return myShowAutoCompleteOnFocus;
        }
        set
        {
            myShowAutoCompleteOnFocus = value;
        }
    }

    public ListBox Lbox
    {
        get
        {
            return myLbox;
        }
    }

    public List<string> AutoCompleteList { get; set; }

    public event EventHandler<clsAutoCompleteEventArgs> BeforeDisplayingAutoComplete;

    public event EventHandler<clsItemSelectedEventArgs> ItemSelected;

    public enum SelectOptions
    {
        None = 0,

        OnEnterPress = 1,

        OnSingleClick = 2,

        OnDoubleClick = 4,

        OnTabPress = 8,

        OnRightArrow = 16,

        OnEnterSingleClick = 3,

        OnEnterSingleDoubleClicks = 7,

        OnEnterDoubleClick = 5,

        OnEnterTab = 9,
    }

    public class clsAutoCompleteEventArgs : EventArgs
    {

        private List<string> myAutoCompleteList;

        private bool myCancel;

        private int mySelectedIndex;

        private List<string> value;

        public int SelectedIndex
        {
            get
            {
                return mySelectedIndex;
            }
            set
            {
                mySelectedIndex = value;
            }
        }

        public bool Cancel
        {
            get
            {
                return myCancel;
            }
            set
            {
                myCancel = value;
            }
        }
        public List<string> AutoCompleteList { get; set; }
    }

    public override string SelectedText
    {
        get
        {
            return base.SelectedText;
        }
        set
        {
            base.SelectedText = value;
        }
    }

    public override int SelectionLength
    {
        get
        {
            return base.SelectionLength;
        }
        set
        {
            base.SelectionLength = value;
        }
    }

    public clsCustomAutoCompleteTextbox()
    {
        HideTimer.Tick += new EventHandler(HideTimer_Tick);
        FocusTimer.Tick += new EventHandler(FocusTimer_Tick);

        myLbox.Click += new EventHandler(myLbox_Click);
        myLbox.DoubleClick += new EventHandler(myLbox_DoubleClick);
        myLbox.GotFocus += new EventHandler(myLbox_GotFocus);
        myLbox.KeyDown += new KeyEventHandler(myLbox_KeyDown);

        myLbox.KeyUp += new KeyEventHandler(myLbox_KeyUp);
        myLbox.LostFocus += new EventHandler(myLbox_LostFocus);
        myLbox.MouseClick += new MouseEventHandler(myLbox_MouseClick);
        myLbox.MouseDoubleClick += new MouseEventHandler(myLbox_MouseDoubleClick);
        myLbox.MouseDown += new MouseEventHandler(myLbox_MouseDown);


        this.GotFocus += new EventHandler(clsCustomAutoCompleteTextbox_GotFocus);
        this.KeyDown += new KeyEventHandler(clsCustomAutoCompleteTextbox_KeyDown);
        this.Leave += new EventHandler(clsCustomAutoCompleteTextbox_Leave);
        this.LostFocus += new EventHandler(clsCustomAutoCompleteTextbox_LostFocus);
        this.Move += new EventHandler(clsCustomAutoCompleteTextbox_Move);
        this.ParentChanged += new EventHandler(clsCustomAutoCompleteTextbox_ParentChanged);


    }

    override protected void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
    {


        base.OnKeyUp(e);
        ShowOnChar(new string(((char)(e.KeyValue)),1));
    }

    private void ShowOnChar(string C)
    {


        if (IsPrintChar(C))
        {
            this.ShowAutoComplete();
        }
    }

    private bool IsPrintChar(int C)
    {


        return IsPrintChar(((char)(C)));
    }

    private bool IsPrintChar(byte C)
    {


        return IsPrintChar(((char)(C)));
    }

    private bool IsPrintChar(char C)
    {


        return IsPrintChar(C.ToString());
    }

    private bool IsPrintChar(string C)
    {

        if (System.Text.RegularExpressions.Regex.IsMatch(C, "[^\\t\\n\\r\\f\\v]"))
        {
            return true;
        }
        else
        {
            return false;
        }

    }

    private void clsCustomAutoCompleteTextbox_GotFocus(object sender, System.EventArgs e)
    {

        if ((!this.SuspendFocus
                    && (this.myShowAutoCompleteOnFocus
                    && (this.myForm.Visible == false))))
        {
            this.ShowAutoComplete();
        }

    }

    private void clsCustomAutoCompleteTextbox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {

        if (!SelectItem(e.KeyCode, false, false))
        {
            if ((e.KeyCode == Keys.Up))
            {
                if ((myLbox.SelectedIndex > 0))
                {
                    MoveLBox((myLbox.SelectedIndex - 1));
                }
            }
            else if ((e.KeyCode == Keys.Down))
            {
                MoveLBox((myLbox.SelectedIndex + 1));
            }
        }

    }

    new void SelectAll()
    {
    }

    private void MoveLBox(int Index)
    {

        try
        {
            if ((Index
                        > (myLbox.Items.Count - 1)))
            {
                Index = (myLbox.Items.Count - 1);
            }
            myLbox.SelectedIndex = Index;
        }
        catch
        {
        }

    }

    private void clsCustomAutoCompleteTextbox_Leave(object sender, System.EventArgs e)
    {

        DoHide(sender, e);

    }

    private void clsCustomAutoCompleteTextbox_LostFocus(object sender, System.EventArgs e)
    {

        DoHide(sender, e);

    }

    private void clsCustomAutoCompleteTextbox_Move(object sender, System.EventArgs e)
    {

        MoveDrop();

    }

    private void clsCustomAutoCompleteTextbox_ParentChanged(object sender, System.EventArgs e)
    {

        if (myParentForm != null) myParentForm.Deactivate -= new EventHandler(myParentForm_Deactivate);
        myParentForm = GetParentForm(this);
        if (myParentForm != null) myParentForm.Deactivate += new EventHandler(myParentForm_Deactivate);
    }

    private void HideTimer_Tick(object sender, System.EventArgs e)
    {

        MoveDrop();
        DoHide(sender, e);
        Cnt++;
        if ((Cnt > 300))
        {
            if (!AppHasFocus(""))
            {
                DoHideAuto();
            }
            Cnt = 0;
        }

    }

    private void myLbox_Click(object sender, System.EventArgs e)
    {
    }

    private void myLbox_DoubleClick(object sender, System.EventArgs e)
    {
    }

    private bool SelectItem(Keys Key, bool SingleClick)
    {
        return SelectItem(Key, SingleClick, false);
    }

    private bool SelectItem(Keys Key)
    {
        return SelectItem(Key, false, false);
    }

    private bool SelectItem(Keys Key, bool SingleClick, bool DoubleClick)
    {

        // Warning!!! Optional parameters not supported
        // Warning!!! Optional parameters not supported
        // Warning!!! Optional parameters not supported
        bool DoSelect = true;
        SelectOptions Meth = SelectOptions.None;
        LastItem = -1;

        if (((this.mySelectionMethods & SelectOptions.OnEnterPress) > 0) && (Key == Keys.Enter))
        {
            Meth = SelectOptions.OnEnterPress;
        }
        else if (((this.mySelectionMethods & SelectOptions.OnRightArrow) > 0) && Key == Keys.Right)
        {
            Meth = SelectOptions.OnRightArrow;
        }
        else if (((this.mySelectionMethods & SelectOptions.OnTabPress) > 0) && Key == Keys.Tab)
        {
            Meth = SelectOptions.OnTabPress;
        }
        else if (((this.mySelectionMethods & SelectOptions.OnSingleClick) > 0) && SingleClick)
        {
            Meth = SelectOptions.OnEnterPress;
        }
        else if (((this.mySelectionMethods & SelectOptions.OnDoubleClick) > 0) && DoubleClick)
        {
            Meth = SelectOptions.OnEnterPress;
        }
        else
        {
            DoSelect = false;
        }

        LastItem = myLbox.SelectedIndex;
        if (DoSelect)
        {
            DoSelectItem(Meth);
        }

        return DoSelect;
    }
    public class clsItemSelectedEventArgs : EventArgs
    {

        private int myIndex;

        private SelectOptions myMethod;

        private string myItemText;

        public clsItemSelectedEventArgs()
        {
        }

        public clsItemSelectedEventArgs(int Index, SelectOptions Method, string ItemText)
        {
            myIndex = Index;
            myMethod = Method;
            myItemText = ItemText;
        }

        public string ItemText
        {
            get
            {
                return myItemText;
            }
            set
            {
                myItemText = value;
            }
        }

        public SelectOptions Method
        {
            get
            {
                return myMethod;
            }
            set
            {
                myMethod = value;
            }
        }

        public int Index
        {
            get
            {
                return myIndex;
            }
            set
            {
                myIndex = value;
            }
        }
    }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, ref int ProcessID);

        private bool AppHasFocus(string ExeNameWithoutExtension)
        {
            bool Out = false;
            // Warning!!! Optional parameters not supported
            int PID = 0;

            if ((ExeNameWithoutExtension == ""))
            {
                ExeNameWithoutExtension = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
            }
            IntPtr activeHandle = GetForegroundWindow();
            GetWindowThreadProcessId(activeHandle, ref PID);
            if ((PID > 0))
            {
                // For Each p As Process In Process.GetProcessesByName(ExeNameWithoutExtension)
                if ((PID == System.Diagnostics.Process.GetCurrentProcess().Id))
                {
                    Out = true;
                }
                //  Next
            }

            return Out;
        }

        private void SaveSelects()
        {
            this.mSelStart = this.SelectionStart;
            this.mSelLength = this.SelectionLength;
        }

        private void LoadSelects()
        {
            this.SelectionStart = this.mSelStart;
            this.SelectionLength = this.mSelLength;
        }

        private void ShowAutoComplete()
        {

            Args = new clsAutoCompleteEventArgs();
            // With...
            Args.Cancel = false;
            Args.AutoCompleteList = this.myAutoCompleteList;
            if ((myLbox.SelectedIndex == -1))
            {
                Args.SelectedIndex = 0;
            }
            else
            {
                Args.SelectedIndex = myLbox.SelectedIndex;
            }

            if (BeforeDisplayingAutoComplete != null) BeforeDisplayingAutoComplete(this, Args);
            this.myAutoCompleteList = Args.AutoCompleteList;
            // If Me.myAutoCompleteList IsNot Nothing AndAlso Me.myAutoCompleteList.Count - 1 < Args.SelectedIndex Then
            //   Args.SelectedIndex = Me.myAutoCompleteList.Count - 1
            // End If
            if ((!Args.Cancel && (Args.AutoCompleteList != null) && Args.AutoCompleteList.Count > 0))
            {
                DoShowAuto();
            }
            else
            {
                DoHideAuto();
            }

        }

        private void DoShowAuto()
        {
            SaveSelects();

            myLbox.BeginUpdate();
            try
            {
                myLbox.Items.Clear();
                myLbox.Items.AddRange(this.myAutoCompleteList.ToArray());
                this.MoveLBox(Args.SelectedIndex);
            }
            catch (Exception ex)
            {
            }
            myLbox.EndUpdate();
            myParentForm = GetParentForm(this);
            if (myParentForm != null)
            {
                myLbox.Name = ("mmmlbox" + DateTime.Now.Millisecond);
                if ((myForm.Visible == false))
                {
                    myForm.Font = this.Font;
                    myLbox.Font = this.Font;
                    myLbox.Visible = true;
                    myForm.Visible = false;
                    myForm.ControlBox = false;
                    myForm.Text = "";
                    if (First)
                    {
                        myForm.Width = this.Width;
                        myForm.Height = 200;
                    }
                    First = false;
                    if (!myForm.Controls.Contains(myLbox))
                    {
                        myForm.Controls.Add(myLbox);
                    }
                    myForm.FormBorderStyle = FormBorderStyle.None;
                    myForm.ShowInTaskbar = false;
                    // With...
                    myLbox.Dock = DockStyle.Fill;
                    myLbox.SelectionMode = SelectionMode.One;
                    // Frm.Controls.Add(myLbox)
                    DontHide = true;
                    SuspendFocus = true;
                    myForm.TopMost = true;
                    myForm.FormBorderStyle = this.myAutoCompleteFormBorder;
                    myForm.BringToFront();
                    MoveDrop();
                    myForm.Visible = true;
                    myForm.Show();
                    MoveDrop();
                    HideTimer.Interval = 10;
                    this.Focus();
                    SuspendFocus = false;
                    HideTimer.Enabled = true;
                    DontHide = false;
                    LoadSelects();
                }
            }

        }

        void MoveDrop()
        {

            Point Pnt = new Point(this.Left, (this.Top
                            + (this.Height + 2)));
            Point ScreenPnt = this.PointToScreen(new Point(-2, this.Height));
            // Dim FrmPnt As Point = Frm.PointToClient(ScreenPnt)
            if (myForm != null)
            {
                myForm.Location = ScreenPnt;
                // myForm.BringToFront()
                // myForm.Focus()
                // myLbox.Focus()
                // Me.Focus()
            }

        }

        void DoHide(object sender, EventArgs e)
        {

            HideAuto();

        }

        private void DFocus(int Delay)
        {

            // Warning!!! Optional parameters not supported
            FocusTimer.Interval = Delay;
            FocusTimer.Start();

        }

        private void DFocus()
        {
            DFocus(10);
        }

        private void DoHideAuto()
        {

            myForm.Hide();
            HideTimer.Enabled = false;
            FocusTimer.Enabled = false;

        }

        private void HideAuto()
        {

            if ((myForm.Visible && HasLostFocus()))
            {
                DoHideAuto();
            }

        }

        private bool HasLostFocus()
        {

            bool Out = false;
            if (this.myForm == null || myForm.ActiveControl != this.myLbox)
            {
                Out = true;
            }
            if (this.myParentForm == null || this.myParentForm.ActiveControl != this)
            {
                Out = true;
            }

            return Out;
        }

        private Form GetParentForm(Control InCon)
        {

            Control TopCon = FindTopParent(InCon);
            Form Out = null;
            if ((TopCon is Form))
            {
                Out = ((Form)(TopCon));
            }

            return Out;
        }

        private Control FindTopParent(Control InCon)
        {

            Control Out;
            if ((InCon.Parent == null))
            {
                Out = InCon;
            }
            else
            {
                Out = FindTopParent(InCon.Parent);
            }

            return Out;
        }

        private void DoSelectItem(SelectOptions Method)
        {

            if (((this.myLbox.Items.Count > 0)
                        && (this.myLbox.SelectedIndex > -1)))
            {
                string Value = this.myLbox.SelectedItem.ToString();
                string Orig = this.Text;
                this.Text = Value;
                if (mySelectTextAfterItemSelect)
                {
                    try
                    {
                        this.SelectionStart = Orig.Length;
                        this.SelectionLength = (Value.Length - Orig.Length);
                    }
                    catch (Exception ex)
                    {
                    }
                }
                else
                {
                    // Me.SelectionStart = Me.Text.Length
                    // Me.SelectionLength = 0
                }

                clsItemSelectedEventArgs a;
                a = new clsItemSelectedEventArgs();
                a.Index = this.myLbox.SelectedIndex;
                a.Method = Method;
                a.ItemText = Value;

                if (ItemSelected != null) ItemSelected(this, a);

                //ItemSelected(this, new clsItemSelectedEventArgs(this.myLbox.SelectedIndex, Method, Value));
                this.DoHideAuto();
            }

        }

        private void myLbox_GotFocus(object sender, System.EventArgs e)
        {

            DFocus();

        }

        private void myLbox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {

            SelectItem(e.KeyCode);

        }

        private void ProcessKeyEvents(KeyEventArgs e)
        {


                if ((e.KeyCode >= Keys.A) && (e.KeyCode <= Keys.Z))
                    base.OnKeyUp(e);


                //Keys.Back;
                //Keys.Enter;
                //Keys.Left;
                //Keys.Right;
                //Keys.Up;
                //Keys.Down;
                //(Keys.NumPad0 & (e.KeyCode <= Keys.NumPad9));
                //(Keys.D0 & (e.KeyCode <= Keys.D9));


        }

        private void myLbox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (IsPrintChar(e.KeyChar))
            {
                // Me.OnKeyPress(e)
                // Call MoveDrop()
            }

        }

        private void myLbox_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (IsPrintChar(e.KeyValue))
            {
                // Me.OnKeyUp(e)
                // Call MoveDrop()
            }

        }

        private void myLbox_LostFocus(object sender, System.EventArgs e)
        {

            DoHide(sender, e);

        }

        private void myLbox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {

            // If e.Button <> Windows.Forms.MouseButtons.None Then
            SelectItem(Keys.None,true);
            // End If

        }

        private void myLbox_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {

            // If e.Button <> Windows.Forms.MouseButtons.None Then
            SelectItem(Keys.None, false, true);
            // End If

        }

        private void myForm_Deactivate(object sender, System.EventArgs e)
        {


        }

        private void myParentForm_Deactivate(object sender, System.EventArgs e)
        {


        }

        private void FocusTimer_Tick(object sender, System.EventArgs e)
        {

            this.Focus();

        }

        private void myLbox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            myLbox_MouseClick(sender, e);
        }
    }
}

关于c# - 子字符串上的 ComboBox 自动完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3694720/

有关c# - 子字符串上的 ComboBox 自动完成的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  4. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  5. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  6. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  7. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  8. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  9. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐