是否有可能在InputBox上有intellisense

时间:2014-09-05 16:10:45

标签: c# winforms intellisense inputbox

在我的Tic Tac Toe游戏中,我向玩家询问他们的名字,我问他们是否希望将其保存。下次他们开始游戏时,我希望InputBox显示某种自动完成状态或IntelliSense即可显示。

问题

如何自动完成或IntelliSense出现在InputBox

仅为了以防万一。我包括:

using Microsoft.VisualBasic;

在我的代码中。

2 个答案:

答案 0 :(得分:1)

为了使用" Intellisense"通过我猜测你的意思"自动完成",您只需设置TextBox并分配其AutoComplete...属性即可。你特别需要的是:

  1. AutoCompleteCustomSource - 这只是一个集合,因此您可以添加自己的字符串列表以用作源。这样您就不必担心DataSet或任何类型的数据库访问,如果您不想这样做。
  2. AutoCompleteMode - 告诉控件它应该是什么类型的AutoComplete输入框。
  3. AutoCompleteSource - 在您的情况下,如果您使用#1作为解决方案,则将其设置为CustomSource。
  4. 修改

    举个例子:

    textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
    textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
    AutoCompleteStringCollection items = new AutoCompleteStringCollection();
    items.Add("Save");
    items.Add("Don't Save");
    
    textBox1.AutoCompleteCustomSource = items;
    

    编辑2

    根据要求,以下是如何逐行阅读文本文件并将其中的数据用作AutoComplete的自定义来源

    string line = "";
    AutoCompleteStringCollection items = new AutoCompleteStringCollection();
    
    // Read the file and display it line by line.
    System.IO.StreamReader file = new System.IO.StreamReader("YOURFILE.txt");
    while((line = file.ReadLine()) != null)
    {
        if(!String.IsNullOrEmpty(line))
        {
            items.Add(line);
        }
    }
    
    file.Close();
    

    希望这有帮助!

答案 1 :(得分:-1)

这是可能的,需要相当多的代码。编写自己的控件可能更好。

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Namespace {

public static class InputBoxEx {

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Form f = new Form();
        Button b = new Button { Text = "Button" };
        f.Controls.Add(b);

        b.Click += delegate {
            String[] words = new[] { "apple", "banana", "carrot" };
            InputBoxEx.ShowInputBox("Prompt", "Title", "Default", -1, -1, words);
        };

        Application.Run(f);
    }

    private static IntPtr hHook = IntPtr.Zero;
    private const int WH_CALLWNDPROCRET = 12;
    private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    private static HookProc hookProc = new HookProc(InputBoxHookProc);
    private static String[] autoCompleteWords = null;

    public static String ShowInputBox(String prompt, String title, String defaultResponse, int xPos = -1, int yPos = -1, String[] autoCompleteWords = null) {
        init(autoCompleteWords);
        return Microsoft.VisualBasic.Interaction.InputBox(prompt, title, defaultResponse, xPos, yPos);
    }

    private static void init(String[] autoCompleteWords) {
        if (hHook != IntPtr.Zero)
            throw new Exception("Cannot be called by multiple threads.");

        InputBoxEx.autoCompleteWords = autoCompleteWords;
        int processID = GetCurrentThreadId();
        hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, processID);
    }

    // returns true if a TextBox is found
    private static bool assignAutoCompleteWords(IntPtr main) {
        List<IntPtr> ptr = GetChildWindows(main);
        foreach (IntPtr p in ptr) {
            TextBox c = Control.FromHandle(p) as TextBox;
            if (c == null)
                continue;

            c.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            c.AutoCompleteSource = AutoCompleteSource.CustomSource;
            c.AutoCompleteCustomSource.AddRange(autoCompleteWords);
            return true;
        }
        return false;
    }

    private enum CbtHookAction : int {
        HCBT_MOVESIZE = 0,
        HCBT_MINMAX = 1,
        HCBT_QS = 2,
        HCBT_CREATEWND = 3,
        HCBT_DESTROYWND = 4,
        HCBT_ACTIVATE = 5,
        HCBT_CLICKSKIPPED = 6,
        HCBT_KEYSKIPPED = 7,
        HCBT_SYSCOMMAND = 8,
        HCBT_SETFOCUS = 9
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct CWPRETSTRUCT {
        public IntPtr lResult;
        public IntPtr lParam;
        public IntPtr wParam;
        public uint message;
        public IntPtr hwnd;
    };

    private static IntPtr InputBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam) {
        if (nCode < 0) {
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }

        CWPRETSTRUCT msg = (CWPRETSTRUCT) Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
        IntPtr hook = hHook;

        if (msg.message == (int) CbtHookAction.HCBT_ACTIVATE) {
            bool unhook = false;
            try {
                unhook = assignAutoCompleteWords(msg.hwnd);
            } catch {
                unhook = true;
            }

            if (unhook) {
                UnhookWindowsHookEx(hHook);
                hHook = IntPtr.Zero;
            }
        }

        return CallNextHookEx(hook, nCode, wParam, lParam);
    }

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

    [DllImport("user32.dll")]
    private static extern int UnhookWindowsHookEx(IntPtr idHook);

    [DllImport("user32.dll")]
    private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
    private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();

    [DllImport("user32.Dll")]
    private static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
    private delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);

    private static List<IntPtr> GetChildWindows(IntPtr parent) {
        List<IntPtr> result = new List<IntPtr>();
        GCHandle listHandle = GCHandle.Alloc(result);
        try {
            Win32Callback childProc = new Win32Callback(EnumWindow);
            EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
        } finally {
            if (listHandle.IsAllocated)
                listHandle.Free();
        }
        return result;
    }

    private static bool EnumWindow(IntPtr handle, IntPtr pointer) {
        GCHandle gch = GCHandle.FromIntPtr(pointer);
        List<IntPtr> list = gch.Target as List<IntPtr>;
        if (list == null)
            throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
        list.Add(handle);
        return true;
    }
}
}