无法在我的函数中访问控件

时间:2015-03-12 14:03:51

标签: c# wpf

只是一个简单的问题,你能告诉我为什么我无法访问我的控件,如弹出窗口或文本框或带有注释的函数内的'this',请检查出来。我真的需要知道为什么尽快。非常感谢你!

/// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DispatcherTimer timer;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);


        public const int WH_KEYBOARD_LL = 13;
        public const int WM_KEYDOWN = 0x0100;
        public static LowLevelKeyboardProc _proc = HookCallback;
        public static IntPtr _hookID = IntPtr.Zero;
        public const uint VK_NUMLOCK = 0x90;
        public const uint VK_CAPITAL = 0x14;

        public MainWindow()
        {
            MouseDown += delegate { DragMove(); };
            InitializeComponent();
            _hookID = SetHook(_proc);
        }

        public void mainForm_Loaded(object sender, RoutedEventArgs e)
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(2000);
            timer.Tick += timer_Tick;
        }

        public void timer_Tick(object sender, EventArgs e)
        {
            Popup1.IsOpen = false;
            timer.Stop();
        }

        public static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode == VK_CAPITAL)
                {
                    if (Console.CapsLock == true)
                    {
                       // I WANT TO ACCESS MY CONTROLS HERE (popup, textbox, etc... this);

                    }
                }



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


        protected override void OnClosed(EventArgs e)
        {
            UnhookWindowsHookEx(_hookID);
            base.OnClosed(e);
        }

    }

2 个答案:

答案 0 :(得分:4)

这是一种静态方法。 &#34;这&#34;控件属于实例,无法在静态方法中看到。

使用这些.dll,我无法提供访问它的防弹方法。我不建议诉诸希望和梦想,但在MainWindow是活动窗口的情况下,您可以执行以下操作:

public static void StaticMainWindowMethod(string incomingMessage)
    {
        var activeWindow = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
        if (activeWindow != null)
        {
            var mainWindow = activeWindow as MainWindow;
            if (mainWindow != null)
            {
                mainWindow.InstanceMainWindowMethod(incomingMessage);
            }
        }
    }

    protected void InstanceMainWindowMethod(string passedFromStaticMessage)
    {
        this.MainTextBox.Text = passedFromStaticMessage;
    }

这个想法是你需要获取窗口的实例才能获得它的属性/控件。根据应用程序的设计方式,您可以通过应用程序级属性获取它。它的可靠性完全取决于应用程序的设计。

答案 1 :(得分:2)

首先,在窗口中添加一个静态事件:

public static event EventHandler CapsLockEnabled;

接下来,为此事件添加处理程序:

public MainWindow()
{
    MouseDown += delegate { DragMove(); };
    InitializeComponent();
    _hookID = SetHook(_proc);

    CapsLockEnabled += (sender, e) => { Console.WriteLine("caps lock enabled"); };
}

您的事件处理程序,因为它在实例上定义,可以完全访问所有窗口的控件。

最后,从您的HookCallback方法提升事件:

public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);
        if (vkCode == VK_CAPITAL)
        {
            if (Console.CapsLock == true)
            {
                var handler = CapsLockEnabled;
                if (handler != null)
                {
                    handler(typeof(MainWindow), EventArgs.Empty);
                }
            }
        }
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}