ব্যবহারকারী কীভাবে "এক্স" বা "ক্লোজ" বোতামটি ক্লিক করেছেন তা কীভাবে জানবেন?


97

এমএসডিএন-তে আমি জানতে পেরেছিলাম CloseReason.UserClosingযে ব্যবহারকারী ফর্মটি বন্ধ করার সিদ্ধান্ত নিয়েছে তবে আমি অনুমান করি যে এক্স বোতামটি ক্লিক করা বা বন্ধ বোতামটি ক্লিক করার ক্ষেত্রে এটি উভয়ই সমান। তাহলে আমি কীভাবে এই কোডগুলিতে এই দুটিয়ের মধ্যে পার্থক্য করতে পারি?

সবাইকে ধন্যবাদ.


4
আপনি কোন বন্ধ বোতাম বলতে চান?
ব্রায়ান আর। বন্ডি

উদাহরণস্বরূপ "ALT + F4" দ্বারা বন্ধ করা
বোহান


@ অলিভার একই প্রশ্ন নয়।
Ctrl এস

উত্তর:


96

ধরে নিই যে আপনি উইনফর্মগুলি চাইছেন , আপনি ফর্মক্লোজিং () ইভেন্টটি ব্যবহার করতে পারেন । কোনও ফর্ম বন্ধ হয়ে যাওয়ার সময় ইভেন্ট ফর্মক্লোজিং () ট্রিগার করা হয়।

ব্যবহারকারী যদি এক্স বা আপনার ক্লোজবটনটি ক্লিক করে থাকে তা সনাক্ত করতে আপনি প্রেরকের অবজেক্টের মাধ্যমে এটি পেতে পারেন। বাটন নিয়ন্ত্রণ হিসাবে প্রেরককে কাস্ট করার চেষ্টা করুন এবং উদাহরণস্বরূপ সম্ভবত এটি "ক্লোজবটন" নামে যাচাই করুন।

private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
    if (string.Equals((sender as Button).Name, @"CloseButton"))
        // Do something proper to CloseButton.
    else
        // Then assume that X has been clicked and act accordingly.
}

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

ALT+ দ্বারা বন্ধ করা F4ফর্মক্লোজিং () ইভেন্টকেও ট্রিগার করবে, কারণ এটি ফর্মটিতে একটি বার্তা প্রেরণ করে যা বন্ধ করে বলে। আপনি ইভেন্টটি সেট করে ইভেন্টটি বাতিল করতে পারেন

FormClosingEventArgs.Cancel = true. 

আমাদের উদাহরণে এটি অনুবাদ হবে

e.Cancel = true.

ফর্মক্লোজিং () এবং ফর্মক্লোজড () ইভেন্টের মধ্যে পার্থক্যটি লক্ষ্য করুন ।

ফর্মটি বন্ধ হওয়ার বার্তাটি পেয়ে গেলে ফর্মক্লোজিং ঘটে এবং এটি বন্ধ হওয়ার আগে এটির কিছু করার আছে কিনা তা যাচাই করে।

ফর্মটি বন্ধ হয় যখন ফর্মটি আসলে বন্ধ থাকে তাই এটি বন্ধ হওয়ার পরে।

এটা কি সাহায্য করে?


হ্যাঁ, "কাস্ট" ধারণার জন্য ধন্যবাদ, ডেলফি 7 এর সাথে এই কৌশলটি ব্যবহার করেছিলেন তবে সি # তে এটি করতে ভুলে গিয়েছিলেন
বোহান

4
আমি এই কোডটি ব্যবহার করার সময় আমি 'অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট না করে' পাই।
নাট এস

34
এটা ভুল. আপনি প্রেরককে বোতামে কাস্ট করতে পারবেন না কারণ এটি ফর্মটি। এটি ব্যতিক্রম ছোঁড়ে।
এক্সট্রো 6'15

4
দয়া করে মনে রাখবেন যে এটি একটি অসম্পূর্ণ উত্তর। দয়া করে এটি উত্সাহিত করবেন না।
নাজিব

4
ব্যবহারকারী @Reza Aghaei দ্বারা উত্তর পরীক্ষা করে দেখুন
নাজিব

79

CloseReasonএমএসডিএন-তে আপনি যে গণনাটি পেয়েছেন তা কেবল ব্যবহারকারী অ্যাপটি বন্ধ করেছে, বা এটি কোনও শাটডাউনের কারণে হয়েছিল, বা টাস্ক ম্যানেজারের মাধ্যমে বন্ধ হয়েছে ইত্যাদি পরীক্ষা করার উদ্দেশ্যে ...

কারণ অনুসারে আপনি বিভিন্ন ক্রিয়া করতে পারেন, যেমন:

void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    if(e.CloseReason == CloseReason.UserClosing)
        // Prompt user to save his data

    if(e.CloseReason == CloseReason.WindowsShutDown)
        // Autosave and clear up ressources
}

তবে আপনি যেমন অনুমান করেছেন, এক্স বোতামটি ক্লিক করা বা টাস্কবারকে ডান ক্লিক করা এবং 'ক্লোজ' ক্লিক করা, বা টিপানো ইত্যাদির মধ্যে কোনও পার্থক্য নেই all এগুলি Alt F4সমস্ত CloseReason.UserClosingকারণেই শেষ হয় ।


11
স্ট্যান্ডার্ড ক্লোজ () ব্যবহার করে; আমার জন্য ক্লোজারেসন.উবারক্লোসিং ট্রিগার করে বলে মনে হচ্ছে। নিশ্চিত কেন।
ড্যান ডাব্লু

ফর্মটিতে ব্যবহারকারীর দ্বারা এমডিআই চাইল্ড ফর্মটি বন্ধ করার চেষ্টা করার সময় আমি এই দরকারীটি পেয়েছি কিন্তু যখন পিতামাতার বন্ধ হচ্ছে তখন নয়।
স্টিভ পেটিফায়ার

4
এটি প্রশ্নের উত্তর দেয় না, কেবল ইস্যুটি আরও গণ্য করে।
রবার্ট কোর্নকে

কীভাবে আপনি এই পদ্ধতিটিকে ইভেন্টটি বাঁধেন?
ব্যবহারকারী 2924019

43

"এক্স" বোতামটি নিবন্ধভুক্ত করে DialogResult.Cancelতাই অন্য একটি বিকল্পটি মূল্যায়ন করা DialogResult

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

(উদাহরণ: btnSubmit.DialogResult = DialogResult.OK, btnClose.DialogResult = Dialogresult.Abort)

    public Form1()
    {
        InitializeComponent();

        this.FormClosing += Form1_FormClosing;
    }

    /// <summary>
    /// Override the Close Form event
    /// Do something
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
    {
        //In case windows is trying to shut down, don't hold the process up
        if (e.CloseReason == CloseReason.WindowsShutDown) return;

        if (this.DialogResult == DialogResult.Cancel)
        {
            // Assume that X has been clicked and act accordingly.
            // Confirm user wants to close
            switch (MessageBox.Show(this, "Are you sure?", "Do you still want ... ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
            {
                //Stay on this form
                case DialogResult.No:
                    e.Cancel = true;
                    break;
                default:
                    break;
            }
        }
    }

4
আমার ক্ষেত্রে এটি গৃহীত উত্তরের চেয়ে বেশি কার্যকর। যেহেতু 'এক্স' ডায়ালগ রিসাল্ট বরাদ্দ করা হয়েছে ance ক্যানসেল, বাতিল বোতামটিতে অন্য কিছু মান নির্ধারণ করে সহজেই তাদের পার্থক্য করে এবং জিনিসগুলিকে যথাযথভাবে পরিচালনা করে।
মিকিফাগেইন_পূর্বএক্সিটঅফসো

4
এটি আমার ক্ষেত্রে কাজ করে না। যখন 'এক্স' টিপুন, DialogResultঅবশেষে None। কি সমস্যা হতে পারে?
ভাস্কার 12

4
@ ভাস্কর, আপনি যখন আপনার ডায়ালগটি ইনস্ট্যান্ট করবেন, আপনার ডায়ালগের প্রতিটি বোতামে উপযুক্ত ডায়ালগের ফলাফল সেট করতে ভুলবেন না। আমি উপরের উদাহরণ দিয়েছি কিন্তু ডায়ালগ ঘোষণাটি প্রকাশ করার জন্য একটি কোড ব্লক তৈরি করিনি।
অ্যালেক্সস্প্রিপ্ট

@Bhaskar: টিপলে Xতোলে DialogResultধারণ Cancelনা NoneNoneআপনার বোতামটি অর্পণ করা এর .DialogResultসম্পত্তি একেবারেই সেট না করা সমান এবং আপনি যদি form.Close()আপনার বোতামের ইভেন্ট হ্যান্ডলার থেকে কল করেন তবে তা form.DialogResultথাকবে Cancel। আপনার সমস্ত ফর্ম-ক্লোজিং বোতাম বাদে Noneবা অন্য কোনও মান নির্ধারণ করা Cancelআপনাকে পছন্দসই পার্থক্য করতে দেয়।
mklement0

12

এক্স বোতামে ক্লিক করে বা Close()কোডে কল করে ফর্মটি বন্ধ করে দেওয়া আছে কীভাবে তা আবিষ্কার করবেন ?

আপনি ইভেন্ট ফর্মটি বন্ধ করার ঘনিষ্ঠ কারণে নির্ভর করতে পারবেন না, কারণ ব্যবহারকারী যদি শিরোনাম বারের এক্স বোতামটি ক্লিক করেন বা Alt + F4 ব্যবহার করে ফর্মটি বন্ধ করেন বা ফর্মটি বন্ধ করার জন্য সিস্টেম মেনু ব্যবহার করেন বা ফর্মটি কলিং Close()পদ্ধতিতে বন্ধ হয়ে যায় , সমস্ত উপরের ক্ষেত্রে, ঘনিষ্ঠ কারণটি ব্যবহারকারী দ্বারা বন্ধ হবে যা পছন্দসই ফলাফল নয়।

এক্স বোতাম বা Closeপদ্ধতি দ্বারা ফর্মটি বন্ধ করা হয়েছে তা আলাদা করতে, আপনি নিম্নলিখিত বিকল্পগুলির মধ্যে দুটি ব্যবহার করতে পারেন:

  • পরিচালনা করুন WM_SYSCOMMANDএবং SC_CLOSEএকটি পতাকা সেট করুন a
  • StackTraceকোনও ফ্রেমে Closeমেথড কল রয়েছে কিনা তা পরীক্ষা করে দেখুন ।

উদাহরণ 1 - হ্যান্ডেল WM_SYSCOMMAND

public bool ClosedByXButtonOrAltF4 {get; private set;}
private const int SC_CLOSE = 0xF060;
private const int WM_SYSCOMMAND = 0x0112;
protected override void WndProc(ref Message msg)
{
    if (msg.Msg == WM_SYSCOMMAND && msg.WParam.ToInt32() == SC_CLOSE)
        ClosedByXButtonOrAltF4 = true;
    base.WndProc(ref msg);
}
protected override void OnShown(EventArgs e)
{
    ClosedByXButtonOrAltF4 = false;
}   
protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (ClosedByXButtonOrAltF4)
        MessageBox.Show("Closed by X or Alt+F4");
    else
        MessageBox.Show("Closed by calling Close()");
}

উদাহরণ 2 - স্ট্যাকট্রেস চেক করা হচ্ছে

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (new StackTrace().GetFrames().Any(x => x.GetMethod().Name == "Close"))
        MessageBox.Show("Closed by calling Close()");
    else
        MessageBox.Show("Closed by X or Alt+F4");
}

4
সুন্দরভাবে সম্পন্ন. খুব খারাপ আপনি পার্টিতে দেরী করেছেন - পুরানো, ইতিমধ্যে অত্যন্ত ভোট দেওয়া উত্তরগুলির সাথে প্রতিযোগিতা করা শক্ত।
mklement0

4
@ mklement0 আমি আশা করি ভবিষ্যতের ব্যবহারকারীরা এটি দরকারী বলে মনে করেন। আমি উত্তরটি পোস্ট করেছিলাম কারণ অন্য উত্তর না থাকলেই সমস্যাটি সঠিকভাবে সমাধান করা যায় এবং এই সংখ্যার মতামত থাকা এবং অত্যধিক ভোট (অ-কর্মক্ষম) উত্তর থাকা একটি প্রশ্নের জন্য এটি বেশ বিস্ময়কর!
রেজা আঘাই

অনেক ধন্যবাদ. আমি ব্যবহার করেছি StackTrace()এবং এটি সমস্যার সমাধান করেছে।
আলী মাজেদ এইচএ

নিবন্ধন করুন
রেজা আhaাহেই

7

কোনও ফর্ম বন্ধ থাকলে অ্যাপ্লিকেশনটি কখন বন্ধ করবেন তা নির্ধারণ করে (যদি আপনার অ্যাপ্লিকেশনটি নির্দিষ্ট ফর্মের সাথে সংযুক্ত না থাকে)।

    private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        if (Application.OpenForms.Count == 0) Application.Exit();
    }

5

আমি আমার অ্যাপ্লিকেশনগুলিতে সর্বদা একটি ফর্ম ক্লোজ পদ্ধতি ব্যবহার করি যা আমার প্রস্থান বোতাম থেকে Alt + x ধরে, Alt + f4 বা অন্য কোনও ফর্ম সমাপন ইভেন্ট শুরু হয়েছিল। আমার সমস্ত ক্লাসের ক্ষেত্রে শ্রেণীর নামটি ব্যক্তিগত স্ট্রিং হিসাবে সংজ্ঞায়িত করা আছে mstrClsTitle = "grmRexcel", একটি প্রস্থান পদ্ধতি যা ফর্ম সমাপ্তি পদ্ধতি এবং একটি ফর্ম সমাপ্তির পদ্ধতি বলে। আমার কাছে ফর্ম বন্ধ করার পদ্ধতির জন্য একটি বিবৃতিও রয়েছে - this.FormClosing = My Form Closing Form Closing method name

এর জন্য কোড:

namespace Rexcel_II
{
    public partial class frmRexcel : Form
    {
        private string mstrClsTitle = "frmRexcel";

        public frmRexcel()
        {
            InitializeComponent();

            this.FormClosing += frmRexcel_FormClosing;
        }

        /// <summary>
        /// Handles the Button Exit Event executed by the Exit Button Click
        /// or Alt + x
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExit_Click(object sender, EventArgs e)
        {            
            this.Close();        
        }


        /// <summary>
        /// Handles the Form Closing event
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmRexcel_FormClosing(object sender, FormClosingEventArgs e)
        {

            // ---- If windows is shutting down, 
            // ---- I don't want to hold up the process
            if (e.CloseReason == CloseReason.WindowsShutDown) return;
            {

                // ---- Ok, Windows is not shutting down so
                // ---- either btnExit or Alt + x or Alt + f4 has been clicked or
                // ---- another form closing event was intiated
                //      *)  Confirm user wants to close the application
                switch (MessageBox.Show(this, 
                                    "Are you sure you want to close the Application?",
                                    mstrClsTitle + ".frmRexcel_FormClosing",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {

                    // ---- *)  if No keep the application alive 
                    //----  *)  else close the application
                    case DialogResult.No:
                        e.Cancel = true;
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

2

আপনি ডিজাইন থেকে ইভেন্ট হ্যান্ডলারটি যুক্ত করার চেষ্টা করতে পারেন: ডিজাইন ভিউতে ফর্মটি খুলুন, বৈশিষ্ট্যগুলি উইন্ডো খুলুন বা এফ 4 টিপুন, ফর্ম অবজেক্টে ইভেন্টগুলি দেখতে ইভেন্ট টুলবার বোতামটি ক্লিক করুন, আচরণ গ্রুপে ফর্মক্লোজিং ইভেন্টটি সন্ধান করুন এবং এটিতে ডাবল ক্লিক করুন। তথ্যসূত্র: https://social.msdn.microsoft.com/ Forums/vstudio/ en- US/ 9bdee708- db4b-4e46-a99c-99726fa25cfb/ how- do-i-add-formclosing-event?forum= csharpgeneral


1
if (this.DialogResult == DialogResult.Cancel)
        {

        }
        else
        {
            switch (e.CloseReason)
            {
                case CloseReason.UserClosing:
                    e.Cancel = true;
                    break;
            }
        }

যদি শর্তটি কার্যকর করা হবে যখন ব্যবহারকারী ফর্মের 'এক্স' বা ক্লোজ বোতামটি ক্লিক করবে। অন্য কোনও ব্যবহারকারীর Alt + f4 ক্লিক করলে অন্যটি ব্যবহার করা যেতে পারে


1
namespace Test
{
    public partial class Member : Form
    {
        public Member()
        {
            InitializeComponent();
        }

        private bool xClicked = true;

        private void btnClose_Click(object sender, EventArgs e)
        {
            xClicked = false;
            Close();
        }

        private void Member_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (xClicked)
            {
                // user click the X
            } 
            else 
            {
                // user click the close button
            }
        }
    }
}

1

আমি DialogResultসমাধানটিকে আরও সহজ সরল ফরওয়ার্ড হিসাবে সম্মত করি ।

ভিবি.এনইটি-তে, টাইপকাস্টের CloseReason-প্রোপার্টি পেতে প্রয়োজনীয়

    Private Sub MyForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing

        Dim eCast As System.Windows.Forms.FormClosingEventArgs
        eCast = TryCast(e, System.Windows.Forms.FormClosingEventArgs)
        If eCast.CloseReason = Windows.Forms.CloseReason.None Then
            MsgBox("Button Pressed")
        Else
            MsgBox("ALT+F4 or [x] or other reason")
        End If

    End Sub

0

আমাকেও ফর্মের "আর্টিনালাইজ কম্পোনেন্ট ()" পদ্ধতির অভ্যন্তরে সমাপনী ফাংশনটি নিবন্ধ করতে হয়েছিল:

private void InitializeComponent() {
// ...
this.FormClosing += FrmMain_FormClosing;
// ...
}

আমার "ফর্মক্লোজিং" ফাংশন প্রদত্ত উত্তরের সাথে একই রকম দেখাচ্ছে ( https://stackoverflow.com/a/2683846/3323790 ):

private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) {
    if (e.CloseReason == CloseReason.UserClosing){
        MessageBox.Show("Closed by User", "UserClosing");
    }

    if (e.CloseReason == CloseReason.WindowsShutDown){
        MessageBox.Show("Closed by Windows shutdown", "WindowsShutDown");
    }
}

আরও একটি বিষয় উল্লেখ করতে হবে: একটি "ফর্মক্লোজড" ফাংশনও রয়েছে যা "ফর্মক্লোজিং" এর পরে ঘটে। এই ফাংশনটি ব্যবহার করতে, নীচের প্রদর্শিত হিসাবে এটি নিবন্ধ করুন:

this.FormClosed += MainPage_FormClosed;

private void MainPage_FormClosing(object sender, FormClosingEventArgs e)
{
// your code after the form is closed
}

0

আমি এরকম কিছু করেছি।

private void Form_FormClosing(object sender, FormClosingEventArgs e)
    {
        if ((sender as Form).ActiveControl is Button)
        {
            //CloseButton
        }
        else
        {
            //The X has been clicked
        }
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.