WPF में सामने की ओर एक विंडो लाएँ


214

मैं अपने WPF एप्लिकेशन को डेस्कटॉप के सामने कैसे ला सकता हूं? अब तक मैंने कोशिश की है:

SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);

SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);

जिनमें से कोई भी काम नहीं कर रहे हैं (Marshal.GetLastWin32Error() कह रहा है कि ये ऑपरेशन सफलतापूर्वक पूरा हो गया है, और प्रत्येक परिभाषा के लिए पी / इनवॉइस विशेषताएँ हैं SetLastError=true)।

अगर मैं एक नया रिक्त WPF एप्लिकेशन बनाता हूं, और कॉल करता हूं SwitchToThisWindow टाइमर के साथ करता हूं, तो यह बिल्कुल अपेक्षा के अनुरूप काम करता है, इसलिए मुझे यकीन नहीं है कि यह मेरे मूल मामले में काम क्यों नहीं कर रहा है।

संपादित करें : मैं यह एक वैश्विक हॉटकी के साथ कर रहा हूं।


क्या आपने सत्यापित किया है कि मेनविंडो वह विंडो है जिसे आप चाहते हैं? MSDN से: MainWindow स्वचालित रूप से AppDomain में तत्काल विंडो ऑब्जेक्ट के संदर्भ में सेट किया जाता है।
टॉड व्हाइट

अच्छा सोचा, लेकिन यह आवेदन में केवल खिड़की है।
फैक्टर मिस्टिक

क्या आप थोड़ा और संदर्भ कोड दे सकते हैं?
टॉड व्हाइट

जवाबों:


314
myWindow.Activate();

खिड़की को अग्रभूमि में लाने का प्रयास करता है और इसे सक्रिय करता है।

जब तक मुझे गलत समझ न आ जाए और आप हमेशा शीर्ष व्यवहार पर रहना चाहते हैं, तब तक यह करना चाहिए। उस मामले में आप चाहते हैं:

myWindow.TopMost = true;

14
मैं बस myWindow.Show () का उपयोग कर रहा था और कभी-कभी यह शीर्ष पर नहीं था। मैंने तुरंत myWindow.Activate () को कॉल किया और इसके बाद काम किया।
बर्मो

4
Windows XP पर कभी-कभी सक्रिय नहीं होता है। मैं @ मट्टू जेवियर के जवाब की सिफारिश करता हूं।
लेक्स ली

थोड़ी अजीब, क्योंकि डिफ़ॉल्ट रूप से ShowActivated चालू है।
ग्रीनल्डमैन

1
पहला उत्तर अच्छा है, इसके लिए धन्यवाद! लेकिन कोड की दूसरी पंक्ति, Topmostसंपत्ति का उपयोग करना एक बुरा अभ्यास है क्योंकि यह अन्य पॉपअप संवादों को अस्पष्ट कर सकता है और अप्रत्याशित व्यवहार कर सकता है।
जोनाथन पेरी

2
वास्तव में यह इस के साथ किया जा सकता है: if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;अजीब तरह से यह किसी भी मैक्सिमाइज़्ड खिड़कियों को संरक्षित करेगा और उन्हें सामान्य स्थिति में वापस नहीं लाएगा।
r41n

168

मुझे एक समाधान मिला है जो खिड़की को शीर्ष पर लाता है, लेकिन यह एक सामान्य खिड़की के रूप में व्यवहार करता है:

if (!Window.IsVisible)
{
    Window.Show();
}

if (Window.WindowState == WindowState.Minimized)
{
    Window.WindowState = WindowState.Normal;
}

Window.Activate();
Window.Topmost = true;  // important
Window.Topmost = false; // important
Window.Focus();         // important

1
महान संकेत! टॉपमोस्ट विंडोज 7 पर जादू करता है अगर खिड़की पहले से खुली है, लेकिन अन्य खिड़कियों के नीचे।
gsb

इसने मेरे लिए भी चाल चली। TopMost के एक अजीब उपयोग की तरह दिखने वाली अतिरिक्त टिप्पणी के लिए gsb का धन्यवाद!
जेन

1
धन्यवाद - तय छोटा और मीठा था।
कोड

2
मेरे मामले में Window.Activate () और Window.Focus () पर्याप्त थे। Window.TopMost सेट करना अनावश्यक है।
virious

6
उपयोग न करें Window.Focus()। यह फ़ोकस को उस चीज़ से दूर ले जाएगा जो उपयोगकर्ता वर्तमान में एक टेक्स्ट बॉक्स में टाइप कर रहा है, जो अंत उपयोगकर्ताओं के लिए निराशाजनक है। उपरोक्त कोड इसके बिना ठीक काम करता है।
कंटैंगो

32

यदि आपको खिड़की के सामने पहली बार लोड होने की आवश्यकता है तो आपको निम्नलिखित का उपयोग करना चाहिए:

private void Window_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
}

private void Window_Initialized(object sender, EventArgs e)
{
    this.Topmost = true;
}

1
यदि आप C # में Launchy ( launchy.net ) के समान कुछ विकसित करते हैं , तो आपको ध्यान देना चाहिए कि यह उत्तर लगभग बेकार है।
लेक्स ली

21

इसे एक त्वरित कॉपी-पेस्ट बनाने के लिए - प्रक्रिया को स्थानांतरित करने के लिए
इस क्लास ' DoOnProcessविधि का उपयोग करें ' मुख्य विंडो को अग्रभूमि में ले जाने के लिए (लेकिन अन्य विंडो से फोकस चोरी करने के लिए नहीं)

public class MoveToForeground
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);

    const int SWP_NOMOVE        = 0x0002;
    const int SWP_NOSIZE        = 0x0001;            
    const int SWP_SHOWWINDOW    = 0x0040;
    const int SWP_NOACTIVATE    = 0x0010;
    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    public static void DoOnProcess(string processName)
    {
        var allProcs = Process.GetProcessesByName(processName);
        if (allProcs.Length > 0)
        {
            Process proc = allProcs[0];
            int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
            // Change behavior by settings the wFlags params. See http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx
            SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
        }
    }
}

HTH


6
+1 यह एकमात्र उत्तर है जो मेरे लिए उपयोगी था। मेरे पास एक मास्टर और कई फ्लोटिंग स्लेव विंडो के साथ एक एप्लिकेशन है। इनमें से किसी को सक्रिय करने पर, अन्य सभी खिड़कियों को भी सामने लाया जाना चाहिए। लेकिन सक्रिय नहीं / फोकस फोकस के रूप में सबसे अधिक उत्तर का सुझाव है: कि एक आपदा है क्योंकि यह खिड़की बनाता है वर्तमान में अचानक से क्लिक किया गया क्लिक करने के बाद से अचानक एक और लाभ।
stijn

उपयोग न करने का कोई कारण process.MainWindowHandle?
श्रीराम सक्थिवेल ६

मेरे मामले में, मैं मुख्य विंडो नहीं चाहता था, लेकिन सहमत हूं, एक होने के अन्य तरीके हैं hWnd। FWIW एक HwndSourceवस्तु ने अच्छी तरह से काम किया।
तोबरींद

21

मुझे पता है कि यह सवाल पुराना है, लेकिन मैं अभी इस सटीक परिदृश्य पर आया हूं और मेरे द्वारा लागू किए गए समाधान को साझा करना चाहता था।

जैसा कि इस पृष्ठ पर टिप्पणियों में उल्लेख किया गया है, प्रस्तावित कई समाधान एक्सपी पर काम नहीं करते हैं, जिन्हें मुझे अपने परिदृश्य में समर्थन करने की आवश्यकता है। जबकि मैं @ मैथ्यू जेवियर की भावना से सहमत हूं कि आम तौर पर यह एक बुरा यूएक्स अभ्यास है, ऐसे समय होते हैं जहां यह पूरी तरह से एक प्रशंसनीय यूएक्स है।

WPF विंडो को शीर्ष पर लाने का समाधान वास्तव में मुझे उसी कोड द्वारा प्रदान किया गया था जिसका उपयोग मैं वैश्विक हॉटकी प्रदान करने के लिए कर रहा हूं। जोसेफ कॉनी के एक ब्लॉग लेख में उनके कोड नमूनों का लिंक है जिसमें मूल कोड शामिल है।

मैंने कोड को साफ किया है और कोड को थोड़ा संशोधित किया है, और इसे System.Windows.Window के विस्तार विधि के रूप में लागू किया है। मैंने इसे एक्सपी 32 बिट और विन 7 64 बिट पर परीक्षण किया है, जो दोनों सही तरीके से काम करते हैं।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace System.Windows
{
    public static class SystemWindows
    {
        #region Constants

        const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 SWP_SHOWWINDOW = 0x0040;

        #endregion

        /// <summary>
        /// Activate a window from anywhere by attaching to the foreground window
        /// </summary>
        public static void GlobalActivate(this Window w)
        {
            //Get the process ID for this window's thread
            var interopHelper = new WindowInteropHelper(w);
            var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);

            //Get the process ID for the foreground window's thread
            var currentForegroundWindow = GetForegroundWindow();
            var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

            //Attach this window's thread to the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

            //Set the window position
            SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

            //Detach this window's thread from the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);

            //Show and activate the window
            if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
            w.Show();
            w.Activate();
        }

        #region Imports

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

        [DllImport("user32.dll")]
        private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        #endregion
    }
}

मुझे उम्मीद है कि यह कोड उन लोगों की मदद करता है जो इस समस्या का सामना करते हैं।


अरे वहाँ देखो! मैं महीनों से इससे जूझ रहा हूँ! यह मेरी दोनों स्थितियों के लिए काम करता है। बहुत बढ़िया! (विंडोज 7 x64)
mdiehl13

वास्तव में, यह केवल तभी काम करता है जब मैं ऐसा करता हूं: App.mainWindow.Show (); SystemWindows.GlobalActivate (App.mainwindow); // जब मैं पहली .show () को हटाता हूँ तो यह सामने नहीं आता
mdiehl13

SetWindowPos () के लिए +1, मैं अन्य ऐप्स को बाधित किए बिना या ध्यान केंद्रित करने के बिना केवल अपनी विंडो को सामने लाने का एक तरीका ढूंढ रहा था। यह। सक्रिय () फोकस चुराता है।

यह मेरे लिए किया था, और यह मेरा मामला पूरे बिंदु फोकस चोरी करने के लिए था, क्योंकि यह तब खुश होता है जब एक उपयोगकर्ता कुछ तत्व के साथ बातचीत करता है। तो बहुत धन्यवाद यह लगातार काम करने लगता है! केवल कॉलिंग this.Activate()केवल कुछ समय के लिए काम करती है।
पीटर

13

यदि उपयोगकर्ता किसी अन्य एप्लिकेशन के साथ सहभागिता कर रहा है, तो हो सकता है कि वह आपके सामने नहीं ला सके। एक सामान्य नियम के रूप में, एक प्रक्रिया केवल अग्रभूमि विंडो को सेट करने की उम्मीद कर सकती है यदि यह प्रक्रिया पहले से ही अग्रभूमि प्रक्रिया है। (Microsoft SetForegroundWindow () MSDN प्रविष्टि में प्रतिबंधों का दस्तावेज़ देता है ।) ऐसा इसलिए है:

  1. उपयोगकर्ता "अग्रभूमि" का मालिक है। उदाहरण के लिए, यदि उपयोगकर्ता टाइप कर रहा हो, तो उसके वर्कफ़्लो में बहुत कम से कम व्यवधान डालने पर दूसरा प्रोग्राम अग्रभूमि चुरा लेता है, और संभवतः अनपेक्षित परिणाम पैदा करता है, क्योंकि जब तक वह बदलाव नहीं देखती है, तब तक यह गलत नहीं होता है। ।
  2. कल्पना करें कि प्रत्येक दो प्रोग्राम यह देखने के लिए जांच करते हैं कि क्या इसकी विंडो अग्रभूमि है और यदि यह नहीं है तो इसे अग्रभूमि में सेट करने का प्रयास करती है। जैसे ही दूसरा कार्यक्रम चल रहा होता है, कंप्यूटर बेकार हो जाता है क्योंकि अग्रभूमि प्रत्येक कार्य स्विच पर दोनों के बीच उछलती है।

अच्छी बात। कोड का उद्देश्य एक वैश्विक हॉटकी के साथ संयोजन के रूप में था, हालांकि, और अन्य अनुप्रयोग इसे किसी भी तरह से करते हैं।
फैक्टर मिस्टिक

इस लेख में बताई गई बातों का अनुकरण करने के लिए C # में PInvoke का उपयोग करना है, codeproject.com/Tips/76427/…
Lex Li

जब मैं कभी-कभी दृश्य स्टूडियो में स्विच करता हूं तो अभिव्यक्ति त्रुटि मिश्रित पॉपअप संवाद क्यों दिखाई देते हैं? : - /
सिमोन_विेवर

साइमन, मुझे संदेह है कि आपके द्वारा देखे गए त्रुटि पॉपअप "सबसे ऊपरी" खिड़कियां हैं (एक डिजाइन निर्णय जिसमें मैं अस्वीकार करता हूं)। अग्रभूमि की खिड़की (जो उपयोगकर्ता इनपुट प्राप्त करती है) और जेड-ऑर्डर में एक "सबसे ऊपरी" खिड़की के बीच अंतर है। कोई भी खिड़की खुद को "सबसे ऊपर" बना सकती है, जो इसे सभी गैर-सबसे ऊपरी खिड़कियों के ऊपर रखती है, लेकिन खिड़की के कीबोर्ड पर ध्यान नहीं देती है, आदि जिस तरह से अग्रभूमि खिड़की बनती है।
मैथ्यू जेवियर

कुछ विशेष विंडो के लिए चाल विफल हो जाती है। विजुअल स्टूडियो और कमांड प्रॉम्प्ट विंडो में कुछ होना चाहिए जो अन्य विंडो को अग्रभूमि विंडो बनने से रोकता है।
लेक्स ली

9

मुझे पता है कि यह देर से जवाब है, शायद शोधकर्ताओं के लिए उपयोगी है

 if (!WindowName.IsVisible)
 {
     WindowName.Show();
     WindowName.Activate();
 }

9

इस पृष्ठ के कुछ उत्तर गलत क्यों हैं!

  • कोई भी उत्तर जो उपयोग करता है window.Focus() वह गलत है।

    • क्यों? यदि कोई सूचना संदेश पॉप अप होता है,window.Focus() तो उपयोगकर्ता उस समय जो भी टाइप कर रहा है, उससे ध्यान हटाएगा। यह अंत उपयोगकर्ताओं के लिए निराशाजनक रूप से निराशाजनक है, खासकर अगर पॉपअप काफी बार होता है।
  • कोई भी उत्तर जो उपयोग करता है window.Activate() वह गलत है।

    • क्यों? यह किसी भी मूल विंडो को भी दिखाई देगा।
  • कोई भी जवाब जो window.ShowActivated = falseगलत है।
    • क्यों? यह ध्यान को दूसरी खिड़की से हटा देगा जब संदेश पॉप अप हो जाएगा जो बहुत कष्टप्रद है!
  • कोई भी उत्तर जो उपयोग नहीं करता है Visibility.Visible खिड़की को छिपाने / दिखाने के लिए है, गलत है।
    • क्यों? यदि हम Citrix का उपयोग कर रहे हैं, यदि विंडो बंद होने पर ढह नहीं जाती है, तो यह स्क्रीन पर एक अजीब काले आयताकार पकड़ को छोड़ देगा। इस प्रकार, हम उपयोग नहीं कर सकते हैं window.Show()और window.Hide()

अनिवार्य रूप से:

  • जब यह सक्रिय हो जाए तो विंडो को किसी अन्य विंडो से फोकस को नहीं हटाना चाहिए;
  • दिखाए जाने पर खिड़की को अपने माता-पिता को सक्रिय नहीं करना चाहिए;
  • खिड़की Citrix के साथ संगत होनी चाहिए।

MVVM समाधान

यह कोड Citrix (स्क्रीन के कोई रिक्त क्षेत्र नहीं) के साथ 100% संगत है। यह सामान्य WPF और DevExpress दोनों के साथ परीक्षण किया जाता है।

यह उत्तर किसी भी उपयोग के मामले के लिए अभिप्रेत है जहां हम एक छोटी अधिसूचना विंडो चाहते हैं जो हमेशा अन्य खिड़कियों के सामने होती है (यदि उपयोगकर्ता वरीयता में इसका चयन करता है)।

यदि यह उत्तर दूसरों की तुलना में अधिक जटिल लगता है, तो यह इसलिए है क्योंकि यह मजबूत, उद्यम स्तर कोड है। इस पृष्ठ पर कुछ अन्य उत्तर सरल हैं, लेकिन वास्तव में काम नहीं करते हैं।

XAML - संलग्न संपत्ति

इस जुड़ी हुई संपत्ति को UserControlखिड़की के भीतर किसी से भी जोड़ें । संलग्न संपत्ति होगी:

  • जब तक Loadedघटना को निकाल दिया जाता है तब तक प्रतीक्षा करें (अन्यथा यह मूल पेड़ को खोजने के लिए दृश्य पेड़ को नहीं देख सकता है)।
  • एक ईवेंट हैंडलर जोड़ें जो यह सुनिश्चित करता है कि विंडो दिखाई दे रही है या नहीं।

किसी भी बिंदु पर, आप संलग्न संपत्ति के मूल्य को फ़्लिप करके, खिड़की को सामने या नहीं होने के लिए सेट कर सकते हैं।

<UserControl x:Class="..."
         ...
         attachedProperties:EnsureWindowInForeground.EnsureWindowInForeground=
             "{Binding EnsureWindowInForeground, Mode=OneWay}">

सी # - हेल्पर विधि

public static class HideAndShowWindowHelper
{
    /// <summary>
    ///     Intent: Ensure that small notification window is on top of other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoForeground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Visible)
            {
                window.Visibility = Visibility.Visible;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = true;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }

    /// <summary>
    ///     Intent: Ensure that small notification window can be hidden by other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoBackground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Collapsed)
            {
                window.Visibility = Visibility.Collapsed;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = false;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }
}

प्रयोग

इसका उपयोग करने के लिए, आपको अपने ViewModel में विंडो बनाने की आवश्यकता है:

private ToastView _toastViewWindow;
private void ShowWindow()
{
    if (_toastViewWindow == null)
    {
        _toastViewWindow = new ToastView();
        _dialogService.Show<ToastView>(this, this, _toastViewWindow, true);
    }
    ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(_toastViewWindow);
    HideAndShowWindowHelper.ShiftWindowIntoForeground(_toastViewWindow);
}

private void HideWindow()
{
    if (_toastViewWindow != null)
    {
        HideAndShowWindowHelper.ShiftWindowIntoBackground(_toastViewWindow);
    }
}

अतिरिक्त लिंक

यह सुनिश्चित करने के लिए कि कैसे एक अधिसूचना विंडो हमेशा दृश्य स्क्रीन पर वापस आ जाती है, मेरा उत्तर देखें: WPF में, स्क्रीन से विंडो को स्क्रीन पर कैसे शिफ्ट किया जाए?


5
"एंटरप्राइज़ स्तर कोड" और बाद में कुछ पंक्तियाँ catch (Exception) { }। हाँ ठीक है ... और यह ऐसे कोड का उपयोग करता है जो उत्तर में _dialogServiceया जैसे भी नहीं दिखाया गया है ShiftWindowOntoScreenHelper। प्लस विंडो को व्यूमोडल साइड में बनाने के लिए कह रहा है (जो मूल रूप से पूरे MVVM पैटर्न को तोड़ता है) ...
Kryptos

@ क्रिप्टोस यह उद्यम स्तर कोड है। मैंने इसे मेमोरी से टाइप किया, और यह सटीक तकनीक एक बड़ी FTSE100 कंपनी में उपयोग की जाती है। वास्तविक जीवन आदर्श डिजाइन पैटर्न की तुलना में कुछ कम प्राचीन है जो हम सभी के लिए लक्ष्य कर रहे हैं।
कंटैंगो

मुझे यह पसंद नहीं है कि हम अपने आप को व्यू मॉडल में विंडो का एक उदाहरण रखें, जैसा कि क्रिप्टोस ने उल्लेख किया है कि mvvm के पूरे बिंदु को तोड़ता है, हो सकता है कि यह कोडबाइंड के बजाय हो सकता है?
इगोर मेस्सरोस

1
@ इगोर मेस्ज़्रोस सहमत। अब जब मेरे पास अधिक अनुभव है, अगर मुझे इसे फिर से करना पड़ा, तो मैं एक व्यवहार जोड़ूंगा, और इसका उपयोग करके नियंत्रण कर सकता हूं Func<>जो ViewModel से जुड़ा हुआ है।
कंटैंगो

7

मुझे WPF एप्लिकेशन के साथ ऐसी ही समस्या हुई है जो शेल ऑब्जेक्ट के माध्यम से एक्सेस एप्लिकेशन से मंगाई जाती है।

मेरा समाधान नीचे है - XP और Win7 x64 में x86 लक्ष्य के लिए संकलित ऐप के साथ काम करता है।

मैं बहुत ज्यादा बल्कि एक टैब टैब अनुकरण करना चाहते हैं।

void Window_Loaded(object sender, RoutedEventArgs e)
{
    // make sure the window is normal or maximised
    // this was the core of the problem for me;
    // even though the default was "Normal", starting it via shell minimised it
    this.WindowState = WindowState.Normal;

    // only required for some scenarios
    this.Activate();
}

4

खैर, चूंकि यह इतना गर्म विषय है ... यहाँ मेरे लिए क्या काम है। अगर मुझे इस तरह से नहीं किया गया तो मुझे त्रुटियां मिलीं क्योंकि अगर आप विंडो नहीं देख सकते हैं तो सक्रिय () आप पर त्रुटि करेगा।

Xaml:

<Window .... 
        Topmost="True" 
        .... 
        ContentRendered="mainWindow_ContentRendered"> .... </Window>

कोड के पीछे:

private void mainWindow_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
    this.Activate();
    _UsernameTextBox.Focus();
}

यह मेरे लिए एकमात्र तरीका था जिससे मुझे शीर्ष पर दिखाने के लिए खिड़की मिल गई। फिर इसे सक्रिय करें ताकि आप बॉक्स में माउस के साथ फोकस किए बिना टाइप कर सकें। नियंत्रण। फ़ोकस () अभ्यस्त काम जब तक खिड़की सक्रिय नहीं है ();


2

अच्छी तरह से मैं एक काम के आसपास लगा। मैं हॉटकी लागू करने के लिए उपयोग किए जाने वाले कीबोर्ड हुक से कॉल कर रहा हूं। कॉल अपेक्षित रूप से काम करता है अगर मैं इसे एक पॉज के साथ बैकग्राउंडवॉकर में डाल देता हूं। यह एक कीचड़ है, लेकिन मुझे नहीं पता कि यह मूल रूप से क्यों काम नहीं कर रहा था।

void hotkey_execute()
{
    IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(delegate
        {
            Thread.Sleep(10);
            SwitchToThisWindow(handle, true);
        });
    bg.RunWorkerAsync();
}

बस दिलचस्पी है: क्या आपने Window.Activate (जैसा कि मोर्टन द्वारा सुझाया गया है) और अन्य सुझाव दिए हैं? वे इस भर्ती किए गए कीचड़ से कम हैक नहीं लगते हैं।
साइमन डी।

यह काफी पहले हो गया है, लेकिन हां, उस समय मैंने कोशिश की थी कि
फैक्टर मिस्टिक

यह मेरे विंडोज एक्सपी पर काम नहीं करता है। मैं @ मट्टू जेवियर के जवाब की सिफारिश करता हूं।
लेक्स ली

2

वर्तमान में खोले गए किसी भी विंडो को दिखाने के लिए उन DLL को आयात करें:

public partial class Form1 : Form
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);
    [DllImportAttribute("User32.dll")]
    private static extern int SetForegroundWindow(int hWnd);

और कार्यक्रम में हम निर्दिष्ट शीर्षक के साथ एप्लिकेशन खोजते हैं (पहले अक्षर के बिना शीर्षक लिखें (सूचकांक> 0))

  foreach (Process proc in Process.GetProcesses())
                {
                    tx = proc.MainWindowTitle.ToString();
                    if (tx.IndexOf("Title of Your app WITHOUT FIRST LETTER") > 0)
                    {
                        tx = proc.MainWindowTitle;
                        hWnd = proc.Handle.ToInt32(); break;
                    }
                }
                hWnd = FindWindow(null, tx);
                if (hWnd > 0)
                {
                    SetForegroundWindow(hWnd);
                }

"FIRST LETTER के बिना आपके ऐप का शीर्षक" Oof, hacky hacky hacky। IndexOfइसके बजाय ठीक से उपयोग क्यों नहीं करते ?
हल्की

1

समस्या यह हो सकती है कि हुक से आपके कोड को कॉल करने वाले धागे को रनटाइम द्वारा प्रारंभ नहीं किया गया है, इसलिए रनटाइम विधियों को कॉल करने से काम नहीं होता है।

शायद आप अपने कोड को कॉल करने के लिए UI कोड पर अपने कोड को मार्शेल करने का प्रयास कर सकते हैं जो विंडो को अग्रभूमि में लाता है।


1

ये कोड हर समय ठीक काम करेंगे।

पहले XAML में सक्रिय ईवेंट हैंडलर सेट करें:

Activated="Window_Activated"

अपने मुख्य विंडो कंस्ट्रक्टर ब्लॉक में नीचे पंक्ति जोड़ें:

public MainWindow()
{
    InitializeComponent();
    this.LocationChanged += (sender, e) => this.Window_Activated(sender, e);
}

और सक्रिय ईवेंट हैंडलर के अंदर इस कोड को कॉपी करें:

private void Window_Activated(object sender, EventArgs e)
{
    if (Application.Current.Windows.Count > 1)
    {
        foreach (Window win in Application.Current.Windows)
            try
            {
                if (!win.Equals(this))
                {
                    if (!win.IsVisible)
                    {
                        win.ShowDialog();
                    }

                    if (win.WindowState == WindowState.Minimized)
                    {
                        win.WindowState = WindowState.Normal;
                    }

                    win.Activate();
                    win.Topmost = true;
                    win.Topmost = false;
                    win.Focus();
                }
            }
            catch { }
    }
    else
        this.Focus();
}

ये चरण ठीक काम करेंगे और अन्य सभी खिड़कियों को उनके माता-पिता की खिड़की के सामने लाएंगे।


0

यदि आप खिड़की को छिपाने की कोशिश कर रहे हैं, उदाहरण के लिए आप खिड़की को छोटा करते हैं, तो मैंने पाया है कि उपयोग करना

    this.Hide();

इसे सही ढंग से छिपाएगा, फिर बस उपयोग कर रहा है

    this.Show();

फिर विंडो को एक बार फिर सबसे ऊपर की वस्तु के रूप में दिखाएगा।


0

बस इस सवाल का एक और समाधान जोड़ना चाहते थे। यह कार्यान्वयन मेरे परिदृश्य के लिए काम करता है, जहां कैलीबर्न मुख्य विंडो को प्रदर्शित करने के लिए जिम्मेदार है।

protected override void OnStartup(object sender, StartupEventArgs e)
{
    DisplayRootViewFor<IMainWindowViewModel>();

    Application.MainWindow.Topmost = true;
    Application.MainWindow.Activate();
    Application.MainWindow.Activated += OnMainWindowActivated;
}

private static void OnMainWindowActivated(object sender, EventArgs e)
{
    var window = sender as Window;
    if (window != null)
    {
        window.Activated -= OnMainWindowActivated;
        window.Topmost = false;
        window.Focus();
    }
}

0

याद रखें उस कोड को न डालें जो उस विंडो को एक पूर्वावलोकन के अंदर दिखाता है। पूर्वावलोकन विंडो सक्रिय हैंडलर के रूप में सक्रिय विंडो उस विंडो पर वापस आ जाएगी, जिसने घटना को संभाला था। बस इसे MouseDoubleClick ईवेंट हैंडलर में रखें या e.Handled को True पर सेट करके बबलिंग बंद करें।

मेरे मामले में मैं एक Listview पर PreviewMouseDoubleClick को हैंडल कर रहा था और e.andled = true को सेट नहीं कर रहा था, फिर इसने माउसडबलक्लिक इवेंट विच को मूल विंडो पर वापस फोकस किया।


-1

मैंने आसान पुन: उपयोग के लिए एक विस्तार विधि का निर्माण किया।

using System.Windows.Forms;
    namespace YourNamespace{
        public static class WindowsFormExtensions {
            public static void PutOnTop(this Form form) {
                form.Show();
                form.Activate();
            }// END PutOnTop()       
        }// END class
    }// END namespace

फॉर्म कंस्ट्रक्टर में कॉल करें

namespace YourNamespace{
       public partial class FormName : Form {
       public FormName(){
            this.PutOnTop();
            InitalizeComponents();
        }// END Constructor
    } // END Form            
}// END namespace

हाय माइक। इस सवाल का जवाब आप काफी देर से दे रहे हैं। क्या आप अपने उत्तर में बता सकते हैं कि यह दृष्टिकोण बहुत अच्छे उत्तरों से अलग (और शायद बेहतर) क्यों है जो पहले से ही इस प्रश्न के लिए पोस्ट किए गए थे?
नोएल विडमर

केवल देर से ही सही मुझे ऐसा करने की आवश्यकता थी, और मैं इस पर आया और यह साझा करना चाहता था कि कैसे मैंने इस समस्या को हल किया, जिससे दूसरे लोग इसका उपयोग करना चाहते थे।
माइक

निश्चित रूप से, मैं आपकी पोस्ट की समीक्षा करने के लिए चुना गया था और आपको जागरूक करना चाहता था। यदि आपको लगता है कि समुदाय के लिए यह एक अच्छा योगदान है, तो एक नया उत्तर प्रदान करना हमेशा अच्छा होता है।
नोएल विडमर

2
यह प्रश्न विशेष रूप से WPF के बारे में था, लेकिन आपका समाधान WinForms के लिए है।
ब्रायन रीचेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.