ডাব্লুপিএফের সামনে একটি উইন্ডো নিয়ে আসুন


214

আমি কীভাবে আমার ডাব্লুপিএফ অ্যাপ্লিকেশনটিকে ডেস্কটপের সামনে আনতে পারি? এখনও পর্যন্ত আমি চেষ্টা করেছি:

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)।

যদি আমি একটি নতুন ফাঁকা ডাব্লুপিএফ অ্যাপ্লিকেশন তৈরি করি এবং SwitchToThisWindowটাইমার সহ কল করি তবে এটি প্রত্যাশার মতো ঠিক কাজ করে, তাই কেন এটি আমার আসল ক্ষেত্রে কাজ করছে না তা আমি নিশ্চিত নই।

সম্পাদনা : আমি একটি বিশ্বব্যাপী হটকি এর সাথে একযোগে এটি করছি।


আপনি কী যাচাই করেছেন যে মেইন উইন্ডোটি আপনি চান উইন্ডো? এমএসডিএন থেকে: মেইন উইন্ডোটি অ্যাপোডোমাইনে ইনস্ট্যান্ট করার জন্য প্রথম উইন্ডো অবজেক্টের একটি রেফারেন্স সহ স্বয়ংক্রিয়ভাবে সেট হয়ে গেছে।
টড হোয়াইট

ভাল চিন্তা, কিন্তু এটি প্রয়োগের একমাত্র উইন্ডো।
ফ্যাক্টর মিস্টিক

আপনি কি আরও কিছু প্রসঙ্গ কোড দিতে পারেন?
টড হোয়াইট

উত্তর:


314
myWindow.Activate();

উইন্ডোটিকে অগ্রভাগে আনার চেষ্টা করা হয় এবং এটি সক্রিয় করে তোলে।

এটি কৌশলটি করা উচিত, যদি না আমি ভুল বোঝে এবং আপনি সর্বদা শীর্ষের আচরণ চান। সেক্ষেত্রে আপনি চান:

myWindow.TopMost = true;

14
আমি কেবল মাই উইন্ডো ব্যবহার করছিলাম h শো () এবং কখনও কখনও এটি শীর্ষে ছিল না। আমি আমার উইন্ডোতে একটি কল রেখেছি cঅ্যাক্টিভেট () এর পরপরই এটি কার্যকর হয়েছিল।
বার্মো

4
অ্যাক্টিভেট কখনও কখনও উইন্ডোজ এক্সপি তে কাজ করে না। আমি @ ম্যাথহে জাভিয়ারের উত্তরটি প্রস্তাব করছি।
লেক্স লি

কিছুটা অদ্ভুত, যেহেতু ডিফল্টরূপে শো-অ্যাক্টিভেটেড চালু।
গ্রীনল্ডম্যান

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 এ উইন্ডো ইতিমধ্যে খোলা থাকলেও অন্য উইন্ডোগুলির নীচে টপমস্ট যাদুটি উইন্ডোজ 7 এ ঘটায়।
জিএসবি

এটি আমার জন্য কৌশলও করেছিল। টপমস্টের এক অদ্ভুত ব্যবহারের মতো দেখতে অতিরিক্ত মন্তব্য করার জন্য জিএসবিকে ধন্যবাদ!
জেন

1
ধন্যবাদ - ফিক্সটি সংক্ষিপ্ত এবং মিষ্টি ছিল।
কোড

2
আমার ক্ষেত্রে উইন্ডো.একটিভেট () এবং উইন্ডো ফোকাস () যথেষ্ট ছিল। উইন্ডো.টপমস্ট সেট করা অপ্রয়োজনীয়।
কৃপণ

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
আপনি যদি সি # তে Launchy ( unchy.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 এই একমাত্র উত্তর যা আমার জন্য দরকারী। আমার এক মাস্টার এবং বেশ কয়েকটি ভাসমান দাস উইন্ডো সহ একটি অ্যাপ্লিকেশন রয়েছে। এগুলির যে কোনওটি সক্রিয় করার পরে, অন্যান্য সমস্ত উইন্ডোগুলিকেও সামনে আনতে হবে। তবে বেশিরভাগ উত্তরের হিসাবে যেমন সক্রিয় / ফোকাস লাভ করা হয়নি: এটি হ'ল একটি দুর্যোগ কারণ এটি উইন্ডোটি বর্তমানে হঠাত্ করে অন্য উইন্ডোতে ফোকাস অর্জনের কারণে উইন্ডোটি ক্লিকযোগ্য করে তোলে।
স্টিজ

ব্যবহার না করার কোনও কারণ process.MainWindowHandle?
শ্রীরাম সাখাটিভেল

আমার ক্ষেত্রে, আমি মূল উইন্ডোটি চাইনি, তবে সম্মত হয়েছি, এটি পাওয়ার অন্যান্য উপায় রয়েছে hWnd। FWIW একটি HwndSourceবস্তু ভাল কাজ করেছে।
tobriand

21

আমি জানি এই প্রশ্নটি বরং পুরানো, তবে আমি কেবল এই সুনির্দিষ্ট দৃশ্যে এসেছি এবং আমি কার্যকর করেছি এমন সমাধানটি ভাগ করে নিতে চাই।

এই পৃষ্ঠায় মন্তব্যে উল্লিখিত হিসাবে, প্রস্তাবিত বেশ কয়েকটি সমাধান এক্সপিতে কাজ করে না, যা আমার দৃশ্যে আমার সমর্থন করা দরকার। যদিও আমি @ ম্যাথেজ জাভিয়ারের অনুভূতির সাথে একমত হই যে সাধারণত এটি একটি খারাপ ইউএক্স অনুশীলন, এমন অনেক সময় আসে যখন এটি সম্পূর্ণরূপে একটি চঞ্চল ইউএক্স হয়।

ডাব্লুপিএফ উইন্ডোটিকে শীর্ষে আনার সমাধানটি আসলে আমি একই কোড দিয়েছিলাম যা আমি বিশ্বব্যাপী হটকি সরবরাহ করতে ব্যবহার করছি। জোসেফ Cooney দ্বারা একটি ব্লগ নিবন্ধ একটি রয়েছে তার কোড নমুনার লিংক আসল কোড রয়েছে।

আমি কোডটি কিছুটা সাফ করেছি এবং সংশোধন করেছি এবং এটিকে System.Windows.Window এ একটি এক্সটেনশন পদ্ধতি হিসাবে প্রয়োগ করেছি। আমি এটি এক্সপি 32 বিট এবং উইন 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); // যখন আমি প্রথমটি সরিয়ে ফেলি। দেখান () এটি সামনে আসে না
mdiehl13

সেট উইন্ডোপোস () এর জন্য +1, আমি অন্য অ্যাপ্লিকেশনগুলিকে বাধা না দিয়ে বা চুরি ফোকাস ছাড়াই কেবল আমার উইন্ডোটি সামনে আনার উপায় খুঁজছিলাম। এটি.অ্যাক্টিভেট () ফোকাস চুরি করে।
সুন্দরভয়েড

এটি আমার জন্য এটি করেছে, এবং এটি আমার ক্ষেত্রে পুরো বিষয়টি ফোকাস চুরি করা ছিল, যখন কোনও ব্যবহারকারী নির্দিষ্ট উপাদানগুলির সাথে ইন্টারঅ্যাক্ট করার সময় এটি সুখী হয়। সুতরাং অনেক ধন্যবাদ এটি ধারাবাহিকভাবে কাজ করে বলে মনে হচ্ছে! কেবল কল করা this.Activate()কিছু সময় কাজ করে বলে মনে হয়।
পিটার

13

যদি ব্যবহারকারী অন্য কোনও অ্যাপ্লিকেশনটির সাথে ইন্টারঅ্যাক্ট করে থাকে তবে আপনার সামনে আনা সম্ভব হবে না। সাধারণ নিয়ম হিসাবে, কোনও প্রক্রিয়া কেবল অগ্রভাগের উইন্ডোটি সেট করার আশা করতে পারে যদি সেই প্রক্রিয়াটি ইতিমধ্যে অগ্রভাগ প্রক্রিয়া হয়। (মাইক্রোসফ্ট সেটফোরগ্রাউন্ড উইন্ডো () এমএসডিএন প্রবেশে বিধিনিষেধগুলিকে নথিভুক্ত করে ) ) এটি কারণ:

  1. ব্যবহারকারী অগ্রভাগটি "মালিকানাধীন"। উদাহরণস্বরূপ, যদি ব্যবহারকারী কোনও টাইপ করার সময় অন্য কোনও প্রোগ্রামের অগ্রভাগ চুরি করে, খুব কমপক্ষে তার কর্মপ্রবাহকে বাধাগ্রস্ত করে এবং সম্ভবত কোনও অনিচ্ছাকৃত পরিণতি ঘটাচ্ছে কারণ কোনও অ্যাপ্লিকেশনের জন্য তার কী-স্ট্রোকগুলি অপরাধীর দ্বারা ভুল ব্যাখ্যা করা না যাওয়া অবধি তার পক্ষে বিরক্তিকর হবে ।
  2. কল্পনা করুন যে দুটি প্রোগ্রামের প্রতিটি তার উইন্ডোটি অগ্রভাগ কিনা তা যাচাই করে এবং যদি তা না হয় তবে অগ্রভাগে সেট করার চেষ্টা করে। দ্বিতীয় প্রোগ্রামটি চলার সাথে সাথে প্রতিটি টাস্ক সুইচে দু'জনের মধ্যে অগ্রভাগটি বাউন্স করার সাথে সাথে কম্পিউটারটি অকেজো হয়ে যায়।

ভাল যুক্তি. কোডটির উদ্দেশ্যটি বিশ্বব্যাপী হটকির সাথে মিলিত ছিল, যদিও অন্যান্য অ্যাপ্লিকেশনগুলি এটি কোনওভাবেই করে।
ফ্যাক্টর মিস্টিক

এই নিবন্ধে বর্ণিত বর্ণনাকে
লেক্স লি

তাহলে আমি মাঝে মাঝে ভিজ্যুয়াল স্টুডিওতে স্যুইচ করি যখন অভিব্যক্তি ত্রুটি পপআপ সংলাপগুলি দৃশ্যমান থাকে কেন? : - /
সাইমন_উইভার

সাইমন, আমি সন্দেহ করি যে আপনি যে ত্রুটি পপআপগুলি দেখছেন তা হ'ল "শীর্ষস্থানীয়" উইন্ডোজ (একটি নকশার সিদ্ধান্ত যা আমি অস্বীকার করি)। অগ্রভাগ উইন্ডো (যা ব্যবহারকারী ইনপুট গ্রহণ করে) এবং জেড-অর্ডারে একটি "শীর্ষস্থানীয়" উইন্ডোর মধ্যে পার্থক্য রয়েছে। যে কোনও উইন্ডো নিজেকে "শীর্ষস্থানীয়" তৈরি করতে পারে, যা এটিকে সমস্ত নন-টপস্টোম উইন্ডোজের উপরে রাখে, তবে উইন্ডো কীবোর্ডকে ফোকাস দেয় না, ইত্যাদি যেমন অগ্রগ্রহ উইন্ডোটি হয়ে যায়।
ম্যাথু জাভিয়ার

কৌশলটি কয়েকটি বিশেষ উইন্ডোর জন্য ব্যর্থ হয়। ভিজ্যুয়াল স্টুডিও এবং কমান্ড প্রম্পট উইন্ডোতে অবশ্যই এমন কিছু থাকতে হবে যা অন্য উইন্ডোটিকে অগ্রভাগ উইন্ডোতে বাধা দেয়।
লেক্স লি

9

আমি জানি যে এটি দেরিতে উত্তর, সম্ভবত গবেষকদের পক্ষে সহায়ক

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

9

এই পৃষ্ঠায় কিছু উত্তর কেন ভুল!

  • যে কোনও উত্তর যা ব্যবহার করে window.Focus()তা ভুল।

    • কেন? যদি কোনও বিজ্ঞপ্তি বার্তা পপ আপ হয়, window.Focus()তবে ব্যবহারকারীরা যা টাইপ করছেন তা দূরে সরিয়ে ফেলবে। এটি শেষ ব্যবহারকারীদের জন্য অত্যন্ত হতাশাবোধক, বিশেষত যদি পপআপগুলি প্রায়শই ঘন ঘন ঘটে।
  • যে কোনও উত্তর যা ব্যবহার করে window.Activate()তা ভুল।

    • কেন? এটি যে কোনও প্যারেন্ট উইন্ডোকে দৃশ্যমান করে তুলবে।
  • বাদ দেওয়া কোনও উত্তর window.ShowActivated = false ভুল।
    • কেন? বার্তাটি পপ আপ হবে যখন এটি খুব বিরক্তিকর হবে যখন এটি অন্য উইন্ডো থেকে ফোকাস দখল করবে!
  • কোনও উত্তর যা ব্যবহার করে না Visibility.Visibleউইন্ডোটি লুকিয়ে / দেখানোর জন্য ভুল।
    • কেন? যদি আমরা সিট্রিক্স ব্যবহার করে থাকি, উইন্ডোটি বন্ধ হয়ে যাওয়ার পরে যদি এটি ভেঙে না যায়, এটি স্ক্রিনে একটি অদ্ভুত কালো আয়তক্ষেত্রাকার জোড় ছেড়ে দেবে। সুতরাং, আমরা ব্যবহার করতে পারি না window.Show()এবং window.Hide()

মূলত:

  • যখন সক্রিয় হয় তখন উইন্ডোটি অন্য কোনও উইন্ডো থেকে ফোকাসকে দখল করা উচিত নয়;
  • উইন্ডোটি যখন প্রদর্শিত হবে তখন তার পিতামাতাকে সক্রিয় করা উচিত নয়;
  • উইন্ডোটি সিট্রিক্সের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত।

এমভিভিএম সলিউশন

এই কোডটি সিট্রিক্সের সাথে 100% উপযুক্ত (পর্দার কোনও ফাঁকা অঞ্চল নেই)) এটি সাধারণ ডাব্লুপিএফ এবং ডেভ এক্সপ্রেস উভয়ই দিয়ে পরীক্ষা করা হয়।

এই উত্তরটি কোনও ব্যবহারের ক্ষেত্রে যেখানে আমরা একটি ছোট বিজ্ঞপ্তি উইন্ডো চাই যা সর্বদা অন্যান্য উইন্ডোগুলির সামনে থাকে (যদি ব্যবহারকারী এটি পছন্দগুলিতে পছন্দ করে) want

যদি এই উত্তরটি অন্যদের তুলনায় আরও জটিল মনে হয় তবে এটি মজবুত, এন্টারপ্রাইজ স্তর কোড। এই পৃষ্ঠার অন্যান্য উত্তরগুলির কয়েকটি সহজ, তবে বাস্তবে কাজ করে না।

এক্সএএমএল - সংযুক্ত সম্পত্তি

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".
        }
    }
}

ব্যবহার

এটি ব্যবহার করতে, আপনার ভিউমোডেলে উইন্ডোটি তৈরি করতে হবে:

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);
    }
}

অতিরিক্ত লিঙ্ক

কোনও বিজ্ঞপ্তি উইন্ডোটি কীভাবে সর্বদা দৃশ্যমান স্ক্রিনে ফিরে আসে তা নিশ্চিত করার জন্য টিপসের জন্য, আমার উত্তরটি দেখুন: ডাব্লুপিএফ-এ, যদি স্ক্রিনটি বন্ধ থাকে তবে উইন্ডোটি কীভাবে স্ক্রিনে স্থানান্তরিত করবেন?


5
"এন্টারপ্রাইজ স্তর কোড" এবং কয়েক লাইন পরে catch (Exception) { }। হ্যাঁ ঠিক ... এবং এটি এমন কোড ব্যবহার করে যা এমনকি উত্তর হিসাবে _dialogServiceবা এমনকি প্রদর্শিত হয় না ShiftWindowOntoScreenHelper। এছাড়াও ভিউমোডেল পাশের উইন্ডোটি তৈরি করতে বলছে (যা মূলত পুরো এমভিভিএম প্যাটার্নটি ভেঙে দেয়) ...
ক্রিপ্টোস

@ ক্রিপ্টোস এটি এন্টারপ্রাইজ লেভেল কোড। আমি এটিকে মেমরি থেকে টাইপ করেছি এবং এই সঠিক কৌশলটি একটি বড় এফটিএসইএস 100 কোম্পানিতে ব্যবহৃত হয়। আমরা প্রত্যক্ষভাবে নিখুঁত নকশার নিদর্শনগুলির তুলনায় বাস্তব জীবন কিছুটা কম আধ্যাত্মিক।
কনটাঙ্গো

আমি সত্যটি পছন্দ করি না যে আমরা উইন্ডোটির একটি উদাহরণ নিজেই ভিউ মডেলে রাখি, যেমন ক্রিপ্টোস উল্লেখ করেছেন যে এমভিভিএমের পুরো পয়েন্টটি ভেঙে ফেলেছে, সম্ভবত এটি কোডবিহিন্ডের পরিবর্তে করা যেত?
ইগর মেসারোস

1
@ ইগর মেসজারোস সম্মত হয়েছেন। এখন যেহেতু আমার আরও অভিজ্ঞতা আছে, যদি আমার এটি আবার করতে হয় তবে আমি এটি একটি আচরণ যুক্ত করব এবং Func<>ভিউমোডেলের সাথে আবদ্ধ একটি ব্যবহার করে এটি নিয়ন্ত্রণ করব।
কনটাঙ্গো

7

আমার ডাব্লুপিএফ অ্যাপ্লিকেশনটির সাথে একই সমস্যা রয়েছে যা শেল অবজেক্টের মাধ্যমে অ্যাক্সেস অ্যাপ্লিকেশন থেকে আহ্বান জানায়।

আমার সমাধানটি নীচে রয়েছে - এক্সপি এবং উইন 7 এক্স 64 এ x86 টার্গেটে সংকলিত অ্যাপ্লিকেশন সহ কাজ করে।

আমি একটি Alt-ট্যাব অনুকরণের চেয়ে অনেক বেশি এটি করতে চাই।

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>

Codebehind:

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();
}

কেবল আগ্রহী: আপনি কি উইন্ডোটি অ্যাক্টিভেট করেছেন (মর্টেনের পরামর্শ অনুসারে) এবং অন্যান্য পরামর্শগুলি? তারা স্বীকৃত এই কুলজের চেয়ে কম হ্যাকি মনে হচ্ছে।
সাইমন ডি

এটি বেশ কিছুক্ষণ আগে হয়েছে, তবে হ্যাঁ, সেই
ফ্যাক্টর মিস্টিক

এটি আমার উইন্ডোজ এক্সপিতে কাজ করে না। আমি @ ম্যাথহে জাভিয়ারের উত্তরটি প্রস্তাব করছি।
লেক্স লি

2

যে কোনও খোলার উইন্ডোটি এই ডিএলএল আমদানি দেখানোর জন্য:

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);
                }

"প্রথম অ্যাপ্লিকেশন ব্যতীত আপনার অ্যাপের শিরোনাম" ওফ, হ্যাকি হ্যাকি হ্যাকি। IndexOfপরিবর্তে সঠিকভাবে ব্যবহার করবেন না কেন ?
bit

1

সমস্যাটি হতে পারে যে আপনার কোডটি হুক থেকে কল করার থ্রেডটি রানটাইম দ্বারা আরম্ভ করা হয়নি তাই রানটাইম পদ্ধতিতে কলিং কাজ করে না।

উইন্ডোটিকে অগ্রভূমিতে নিয়ে আসে এমন আপনার কোডটি কল করতে আপনি সম্ভবত আপনার কোডটি ইউআই থ্রেডে মার্শাল করার চেষ্টা করতে পারেন।


1

এই কোডগুলি সর্বদা সূক্ষ্মভাবে কাজ করবে।

প্রথমে এক্সএএমএলে সক্রিয় ইভেন্ট হ্যান্ডলারটি সেট করুন:

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

সক্রিয় উইন্ডোটি ইভেন্টটি পরিচালনা করে এমন উইন্ডোটিতে আবার স্যুইচ করবে বলে কোডটি প্রিভিউমাউসডাবলক্লিক হ্যান্ডলারের অভ্যন্তরে সেই উইন্ডোটি দেখায় এমন কোডটি রাখবেন না Remember এটিকে কেবল মাউসডুবলক্লিক ইভেন্ট হ্যান্ডলারের মধ্যে রেখে দিন বা ই-হ্যান্ডলড ট্রু সেট করে বুদবুদ বন্ধ করুন।

আমার ক্ষেত্রে আমি প্রিভিউমাউসডুবলক্লিকে একটি তালিকার ভিউতে পরিচালনা করছি এবং ই-হ্যান্ডলড = সত্য সেট করছিলাম না তবে এটি মাউসডুবলক্লিক ইভেন্ট ডাইনীটিকে মূল উইন্ডোতে ফিরে ফোকাস উত্থাপন করেছে।


-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
এই প্রশ্নটি বিশেষত ডাব্লুপিএফ সম্পর্কে ছিল, তবে আপনার সমাধানটি উইনফোর্ডসের জন্য।
ব্রায়ান রিচল 20'17
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.