WPF विंडो में क्लोज बटन कैसे छिपाएं?


204

मैं WPF में एक मोडल डायलॉग लिख रहा हूँ। एक करीब बटन न होने के लिए मैं एक WPF विंडो कैसे सेट करूं? मैं अभी भी इसके WindowStateलिए एक सामान्य शीर्षक पट्टी रखना चाहूंगा ।

मैंने पाया ResizeMode, WindowStateऔर WindowStyle, लेकिन उन गुणों में से कोई भी मुझे बंद बटन को छिपाने की अनुमति नहीं देता है, लेकिन टाइटल बार दिखा सकता है, जैसा कि मोडल संवादों में है।


9
यह एक बैकग्राउंड थ्रेड चलाने वाला प्रगति संवाद है जो रद्द करने का समर्थन नहीं करता है; मुझे लगता है कि मैं इसे बनाने की कोशिश कर रहा हूं इसलिए मुझे रद्द करने (अभी तक) का समर्थन नहीं करना है। तुम शायद सही हो, यद्यपि।
माइकल हेडगपेथ

1
मुझे विंडो क्रोम को हटाने की कोशिश करने वाले ऐप्स से भी नफरत है। यदि मैं एक प्रगति संवाद करता हूं, तो मैं हमेशा विंडो बंद करता हूं बटन को वास्तविक रद्द करें बटन पर क्लिक करने के समान तर्क देता है।
क्रिश्चियन हैटर

13
क्रिस के लिए: आइए कल्पना करें कि आपका सॉफ्टवेयर वीडियो निगरानी के लिए है। रात के दौरान एक सुरक्षा एजेंट एचएएस (यही उसका काम है) खिड़कियों को खोलकर रखना ... लेकिन कभी-कभी उनका काम उबाऊ होता है और वे किसी भी कारण से इंटरनेट मैट्रिसेज विंडो को सर्फ करना या बंद करना चाहते हैं, खिड़कियों के बटन को हटाना उचित तरीका है इसे करने के लिए।
जीन-मैरी

7
@ChrisUpchurch, "आप ऐसा क्यों करना चाहते हैं? यह मुझे वास्तव में घटिया यूआई डिज़ाइन के रूप में प्रभावित करता है।" - वास्तव में "घटिया यूआई डिज़ाइन" है जब एक प्रोग्राम ओके के साथ एक संवाद बॉक्स प्रस्तुत करता है ; रद्द करें और बंद करें बटन। उपयोगकर्ता के लिए, यह स्पष्ट नहीं हो सकता है कि क्लोज़ क्या करता है। इसे रद्द करता है या जमा करता है ? आम सहमति संवादों में घनिष्ठ बटन शामिल करने के लिए नहीं है, इसलिए यह है कि
मिकी डी

1
@ जीन-मैरी लेकिन क्लोज बटन को छुपाने से ऐसा नहीं होता है, यह केवल अनजान और आलसी (Google के लिए) को बेवकूफ बनाता है। क्लोज बटन को छिपाने से केवल उस बटन को क्लिक करने से रोकता है। जीत कुंजी और Alt कुंजी कॉम्बो अभी भी सामान्य रूप से काम करेंगे "इसे करने के लिए" उचित "तरीका है, श्रमिकों के लिए एक उपयोगकर्ता खाता बनाना है, एक समूह नीति के साथ जो उन्हें स्वीकृत किए जाने के अलावा किसी भी सॉफ़्टवेयर को खोलने / स्थापित करने से रोकता है। किसी भी रखरखाव को संभालने के लिए व्यवस्थापक खाते, कि पर्यवेक्षकों तक पहुंच है।
डिजिटल_ यूटोपिया

जवाबों:


275

शीर्षक बार के क्लोज बटन को छिपाने के लिए WPF के पास बिल्ट-इन प्रॉपर्टी नहीं है, लेकिन आप इसे P / Invoke की कुछ लाइनों के साथ कर सकते हैं।

सबसे पहले, इन घोषणाओं को अपने विंडो वर्ग में जोड़ें:

private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

फिर विंडो के Loadedईवेंट में यह कोड डालें :

var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);

और वहाँ तुम जाओ: कोई और अधिक बंद बटन। आपको शीर्षक बार के बाईं ओर एक विंडो आइकन नहीं होगा, जिसका अर्थ है कि कोई सिस्टम मेनू नहीं, यहां तक ​​कि जब आप शीर्षक बार पर राइट-क्लिक करते हैं - तो वे सभी एक साथ चलते हैं।

ध्यान दें कि Alt+ F4अभी भी विंडो बंद करेगा। यदि आप पृष्ठभूमि थ्रेड होने से पहले विंडो को बंद करने की अनुमति नहीं देना चाहते हैं, तो आप ओवरराइड कर सकते हैं OnClosingऔर Cancelसही पर सेट कर सकते हैं , जैसा कि गाबे ने सुझाव दिया था।


5
डॉक्स के अनुसार हमें SetWindowLongPtrइसके बजाय उपयोग करना चाहिए ।
जोनाथन एलेन

15
ज्यादातर स्वयं के लिए एक नोट ... DllImport का नाम -> System.Runtime.InteropServices.DllImport। WindowInteropHelper के नामस्थान -> System.Windows.Interop.WindowInteropHelper
doobop

3
दरअसल, यह दृष्टिकोण तीनों बटन (मिन, मैक्स और क्लोज) को छुपाता है। क्या केवल बंद बटन को छिपाना संभव है?
न्यूमैन

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

3
अपने विंडो टैग पर XAML फ़ाइल में WindowStyle = "none" डालें।
डाइगोड्स

88

मैं बस इसी तरह की समस्या के लिए मिला और जो व्हाइट का समाधान मुझे सरल और साफ लगता है। मैंने इसे पुन: उपयोग किया और इसे विंडो की संलग्न संपत्ति के रूप में परिभाषित किया

public class WindowBehavior
{
    private static readonly Type OwnerType = typeof (WindowBehavior);

    #region HideCloseButton (attached property)

    public static readonly DependencyProperty HideCloseButtonProperty =
        DependencyProperty.RegisterAttached(
            "HideCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false, new PropertyChangedCallback(HideCloseButtonChangedCallback)));

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetHideCloseButton(Window obj) {
        return (bool)obj.GetValue(HideCloseButtonProperty);
    }

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static void SetHideCloseButton(Window obj, bool value) {
        obj.SetValue(HideCloseButtonProperty, value);
    }

    private static void HideCloseButtonChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var window = d as Window;
        if (window == null) return;

        var hideCloseButton = (bool)e.NewValue;
        if (hideCloseButton && !GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded += HideWhenLoadedDelegate;
            }
            else {
                HideCloseButton(window);
            }
            SetIsHiddenCloseButton(window, true);
        }
        else if (!hideCloseButton && GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded -= ShowWhenLoadedDelegate;
            }
            else {
                ShowCloseButton(window);
            }
            SetIsHiddenCloseButton(window, false);
        }
    }

    #region Win32 imports

    private const int GWL_STYLE = -16;
    private const int WS_SYSMENU = 0x80000;
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    #endregion

    private static readonly RoutedEventHandler HideWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        HideCloseButton(w);
        w.Loaded -= HideWhenLoadedDelegate;
    };

    private static readonly RoutedEventHandler ShowWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        ShowCloseButton(w);
        w.Loaded -= ShowWhenLoadedDelegate;
    };

    private static void HideCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }

    private static void ShowCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
    }

    #endregion

    #region IsHiddenCloseButton (readonly attached property)

    private static readonly DependencyPropertyKey IsHiddenCloseButtonKey =
        DependencyProperty.RegisterAttachedReadOnly(
            "IsHiddenCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false));

    public static readonly DependencyProperty IsHiddenCloseButtonProperty =
        IsHiddenCloseButtonKey.DependencyProperty;

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetIsHiddenCloseButton(Window obj) {
        return (bool)obj.GetValue(IsHiddenCloseButtonProperty);
    }

    private static void SetIsHiddenCloseButton(Window obj, bool value) {
        obj.SetValue(IsHiddenCloseButtonKey, value);
    }

    #endregion

}

फिर XAML में आपने इसे इस तरह सेट किया:

<Window 
    x:Class="WafClient.Presentation.Views.SampleWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:u="clr-namespace:WafClient.Presentation.Behaviors"
    ResizeMode="NoResize"
    u:WindowBehavior.HideCloseButton="True">
    ...
</Window>

62

WindowStyleप्रॉपर्टी को कोई भी सेट करें जो टाइटल बार के साथ कंट्रोल बॉक्स को छिपा देगा। कॉल करने के लिए कोई ज़रूरत नहीं है।


20
खैर, यह विंडो टाइटल बार को पूरी तरह से छिपा देगा। इसका मतलब है कि आपको विंडो टाइटल नहीं मिलेगा और यूजर विंडो को मूव नहीं कर पाएंगे।
न्यूमैन

6
आप जोड़कर खिड़की चल कर सकते हैं this.DragMove();विंडो के लिए MouseDownघटना
पॉल

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

1
मुझे लगता है कि कुछ लोग एक सीमा रखना चाहेंगे, हालांकि
pjdupreez

2
निश्चित रूप से सबसे अच्छा समाधान। पैनल में सीमा जोड़ने, या चलती को लागू करने के साथ कोई समस्या नहीं है।
buks

50

यह बंद बटन से छुटकारा नहीं मिलेगा, लेकिन यह किसी को खिड़की बंद करने से रोक देगा।

इसे फ़ाइल के पीछे अपने कोड में रखें:

protected override void OnClosing(CancelEventArgs e)
{
   base.OnClosing(e);
   e.Cancel = true;
}

7
विदित हो कि ऐसा करना Windowएक मोडल डायलॉग के रूप में Windowस्थापित किया गया है जो इसकी DialogResultसंपत्ति की सेटिंग में हस्तक्षेप करेगा और इसे अनुपयोगी बना सकता है। stackoverflow.com/questions/898708/cant-set-dialogresult-in-wpf
Sheridan

4
मुझे इस विधि का उपयोग करके एक अतिप्रवाह हो रहा था, मैंने आधार निकाल लिया। एन क्लोजिंग (ई) और फिर इसने काम किया
जेकॉब्सग्रिफ़िथ

8
एक उपयोगकर्ता के रूप में मैं प्रोग्रामर से नफरत करता हूँ जिन्होंने इसे अपने आवेदन में डाला है
UrbanEsc

2
@UrbanEsc मैं सहमत होना चाहूंगा कि इसकी कष्टप्रद बात है, लेकिन जब मैंने ऐसा किया - और यह केवल एक समय था - यह एक अनिवार्य आवश्यकता थी, और यह एक आवश्यक बुराई थी, कुछ बहुत महत्वपूर्ण प्रक्रिया चल रही थी यह बाधित नहीं किया जा सका और जब तक ऐसा नहीं किया गया, ऐप आगे नहीं बढ़ सका। अन्य तरीके भी हो सकते थे (एक बैकग्राउंड थ्रेड, यूआई के साथ तैयार होने तक विकलांग) लेकिन बॉस और क्लाइंट दोनों ने इसे इस तरह से पसंद किया क्योंकि इसने प्रक्रिया की गंभीरता पर जोर दिया।
फ़्लबियस 20

15

क्लोज़ बटन को निष्क्रिय करने के लिए आपको अपने विंडो क्लास में निम्न कोड जोड़ना चाहिए (कोड यहाँ से लिया गया था , संपादित और थोड़ा सुधार किया गया):

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

    if (hwndSource != null)
    {
        hwndSource.AddHook(HwndSourceHook);
    }

}

private bool allowClosing = false;

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);

private const uint MF_BYCOMMAND = 0x00000000;
private const uint MF_GRAYED = 0x00000001;

private const uint SC_CLOSE = 0xF060;

private const int WM_SHOWWINDOW = 0x00000018;
private const int WM_CLOSE = 0x10;

private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WM_SHOWWINDOW:
            {
                IntPtr hMenu = GetSystemMenu(hwnd, false);
                if (hMenu != IntPtr.Zero)
                {
                    EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
                }
            }
            break;
        case WM_CLOSE:
            if (!allowClosing)
            {
                handled = true;
            }
            break;
    }
    return IntPtr.Zero;
}

यह कोड सिस्टम मेनू में करीबी आइटम को भी निष्क्रिय कर देता है और Alt + F4 का उपयोग करके संवाद को बंद कर देता है।

आप संभवतः प्रोग्राम को विंडो बंद करना चाहेंगे। सिर्फ बुलाने Close()से काम नहीं चलेगा। कुछ इस तरह से करें:

allowClosing = true;
Close();

विंडोज 7 में: ऊपर भी ड्रॉप-डाउन सिस्टम मेनू में बंद आइटम को अक्षम करता है (लेकिन हटाता नहीं है)। बंद बटन स्वयं अक्षम है (ग्रे दिखता है), लेकिन हटाया नहीं गया। यह ट्रिक न्यूनतम / अधिकतम आइटम / बटन के लिए काम नहीं करता है - मुझे संदेह है कि WPF उन्हें पुनः सक्षम करता है।

3
बटन को निष्क्रिय करने से बेहतर है कि उन्हें हटा दिया जाए, इससे उपयोगकर्ता को यह पता चलता है कि एक महत्वपूर्ण ऑपरेशन चल रहा है।
रॉबर्ट बेकर

10

मैं वायाचसलाऊ के उत्तर की कोशिश कर रहा था क्योंकि मुझे बटन को हटाने के लिए नहीं बल्कि इसे अक्षम करने का विचार पसंद है, लेकिन किसी कारण से यह हमेशा काम नहीं करता था: करीबी बटन अभी भी सक्षम था लेकिन कोई भी त्रुटि नहीं।

दूसरी ओर यह हमेशा काम किया (त्रुटि जाँच छोड़ा गया):

[DllImport( "user32.dll" )]
private static extern IntPtr GetSystemMenu( IntPtr hWnd, bool bRevert );
[DllImport( "user32.dll" )]
private static extern bool EnableMenuItem( IntPtr hMenu, uint uIDEnableItem, uint uEnable );

private const uint MF_BYCOMMAND = 0x00000000;
private const uint MF_GRAYED = 0x00000001;
private const uint SC_CLOSE = 0xF060;
private const int WM_SHOWWINDOW = 0x00000018;

protected override void OnSourceInitialized( EventArgs e )
{
  base.OnSourceInitialized( e );
  var hWnd = new WindowInteropHelper( this );
  var sysMenu = GetSystemMenu( hWnd.Handle, false );
  EnableMenuItem( sysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );
}

1
उत्तम! Windowमेरी परियोजना में एक विस्तार विधि के रूप में जोड़ा गया ।
मैट डेविस

8

सेट करने का गुण => है WindowStyle="None"

<Window x:Class="mdaframework.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Start" Height="350" Width="525" ResizeMode="NoResize"  WindowStartupLocation="CenterScreen" WindowStyle="None">

4
यह भी अधिकतम / मिनट बटन छुपाता है
वोट कॉफ़ी

3
यह पूरे शीर्षक पट्टी को हटाता है, बॉक्स को बदसूरत और बिना विवरण के प्रतिपादन करता है। शॉटगन दृष्टिकोण और एक डुप्लिकेट उत्तर। Downvote।
vapcguy

यह कियोस्क अनुप्रयोगों के लिए सबसे अच्छा समाधान है जिसे हमेशा अपने आवेदन को अधिकतम करने की आवश्यकता होती है और ग्राहकों को ऐप को बंद करने की अनुमति नहीं देनी चाहिए। तो अपवोट
राजोन तंदुकर

8

मैं सिर्फ अन्तरक्रियाशीलता व्यवहार का उपयोग करते हुए जो व्हाइट के उत्तर को लागू करता हूं (आपको System.Windows.Interactivity को संदर्भित करने की आवश्यकता है)।

कोड:

public class HideCloseButtonOnWindow : Behavior<Window>
{
    #region bunch of native methods

    private const int GWL_STYLE = -16;
    private const int WS_SYSMENU = 0x80000;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    #endregion

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += OnLoaded;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Loaded -= OnLoaded;
        base.OnDetaching();
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        var hwnd = new WindowInteropHelper(AssociatedObject).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }
}

उपयोग:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:w="clr-namespace:WpfApplication2">

    <i:Interaction.Behaviors>
        <w:HideCloseButtonOnWindow />
    </i:Interaction.Behaviors>

</Window>

2

उपयोगकर्ता को विंडो को "बंद" करने दें लेकिन वास्तव में इसे छिपाएं।

विंडो के ऑनक्लोज़िंग ईवेंट में, यदि पहले से ही दिखाई दे रही हो तो विंडो छिपाएँ:

    If Me.Visibility = Windows.Visibility.Visible Then
        Me.Visibility = Windows.Visibility.Hidden
        e.Cancel = True
    End If

हर बार जब बैकग्राउंड थ्रेड निष्पादित किया जाना है, तो बैकग्राउंड यूआई विंडो दिखाएं:

    w.Visibility = Windows.Visibility.Visible
    w.Show()

कार्यक्रम के निष्पादन को समाप्त करते समय, सुनिश्चित करें कि सभी विंडो बंद / बंद हो सकती हैं:

Private Sub CloseAll()
    If w IsNot Nothing Then
        w.Visibility = Windows.Visibility.Collapsed ' Tell OnClosing to really close
        w.Close()
    End If
End Sub

1

तो, यहाँ बहुत ज्यादा आपकी समस्या है। विंडो फ़्रेम के ऊपरी दाईं ओर का नज़दीकी बटन WPF विंडो का हिस्सा नहीं है, लेकिन यह उस विंडो फ़्रेम के हिस्से से संबंधित है जिसे आपके OS द्वारा नियंत्रित किया जाता है। इसका मतलब है कि आपको इसे करने के लिए Win32 इंटरॉप का उपयोग करना होगा।

वैकल्पिक रूप से, आप नोफ्रेम का उपयोग कर सकते हैं और या तो अपना खुद का "फ्रेम" प्रदान कर सकते हैं या इसमें कोई फ्रेम नहीं है।


1

निम्नलिखित करीब और अधिकतम / छोटा बटन अक्षम करने के बारे में है, यह वास्तव में बटन को नहीं हटाता है (लेकिन यह मेनू आइटम करता है!)। शीर्षक पट्टी पर बटन अक्षम / ग्रे अवस्था में खींचे जाते हैं। (मैं पूरी कार्यक्षमता के लिए खुद तैयार नहीं हूं ^ ^)

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

/ बटन, के रूप में बंद करें बटन के विपरीत, मेनू से प्रविष्टियां निकालने सिस्टम बटन "अक्षम" रेंडर करने के लिए भले ही मेनू प्रविष्टियां निकालने का कारण नहीं है कम से कम का पालन कोड भी अधिकतम अक्षम करने का समर्थन करता है करता है बटन के अक्षम कार्यक्षमता।

इससे मेरा काम बनता है। YMMV।

    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.Runtime.InteropServices;
    using Window = System.Windows.Window;
    using WindowInteropHelper = System.Windows.Interop.WindowInteropHelper;
    using Win32Exception = System.ComponentModel.Win32Exception;

    namespace Channelmatter.Guppy
    {

        public class WindowUtil
        {
            const int MF_BYCOMMAND = 0x0000;
            const int MF_BYPOSITION = 0x0400;

            const uint MFT_SEPARATOR = 0x0800;

            const uint MIIM_FTYPE = 0x0100;

            [DllImport("user32", SetLastError=true)]
            private static extern uint RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags);

            [DllImport("user32", SetLastError=true)]
            private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemCount(IntPtr hWnd);

            [StructLayout(LayoutKind.Sequential)]
            public struct MenuItemInfo {
                public uint   cbSize;
                public uint   fMask;
                public uint   fType;
                public uint   fState;
                public uint   wID;
                public IntPtr hSubMenu;
                public IntPtr hbmpChecked;
                public IntPtr hbmpUnchecked;
                public IntPtr dwItemData; // ULONG_PTR
                public IntPtr dwTypeData;
                public uint   cch;
                public IntPtr hbmpItem;
            };

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemInfo(
                IntPtr hMenu, uint uItem,
                bool fByPosition, ref MenuItemInfo itemInfo);

            public enum MenuCommand : uint
            {
                SC_CLOSE = 0xF060,
                SC_MAXIMIZE = 0xF030,
            }

            public static void WithSystemMenu (Window win, Action<IntPtr> action) {
                var interop = new WindowInteropHelper(win);
                IntPtr hMenu = GetSystemMenu(interop.Handle, false);
                if (hMenu == IntPtr.Zero) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get system menu");
                } else {
                    action(hMenu);
                }
            }

            // Removes the menu item for the specific command.
            // This will disable and gray the Close button and disable the
            // functionality behind the Maximize/Minimuze buttons, but it won't
            // gray out the Maximize/Minimize buttons. It will also not stop
            // the default Alt+F4 behavior.
            public static void RemoveMenuItem (Window win, MenuCommand command) {
                WithSystemMenu(win, (hMenu) => {
                    if (RemoveMenu(hMenu, (uint)command, MF_BYCOMMAND) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to remove menu item");
                    }
                });
            }

            public static bool RemoveTrailingSeparator (Window win) {
                bool result = false; // Func<...> not in .NET3 :-/
                WithSystemMenu(win, (hMenu) => {
                    result = RemoveTrailingSeparator(hMenu);
                });
                return result;
            }

            // Removes the final trailing separator of a menu if it exists.
            // Returns true if a separator is removed.
            public static bool RemoveTrailingSeparator (IntPtr hMenu) {
                int menuItemCount = GetMenuItemCount(hMenu);
                if (menuItemCount < 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get menu item count");
                }
                if (menuItemCount == 0) {
                    return false;
                } else {
                    uint index = (uint)(menuItemCount - 1);
                    MenuItemInfo itemInfo = new MenuItemInfo {
                        cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)),
                        fMask = MIIM_FTYPE,
                    };

                    if (GetMenuItemInfo(hMenu, index, true, ref itemInfo) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to get menu item info");
                    }

                    if (itemInfo.fType == MFT_SEPARATOR) {
                        if (RemoveMenu(hMenu, index, MF_BYPOSITION) == 0) {
                            throw new Win32Exception(Marshal.GetLastWin32Error(),
                                "Failed to remove menu item");
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
            }

            private const int GWL_STYLE = -16;

            [Flags]
            public enum WindowStyle : int
            {
                WS_MINIMIZEBOX = 0x00020000,
                WS_MAXIMIZEBOX = 0x00010000,
            }

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int SetWindowLong (IntPtr hWnd, int nIndex, int dwNewLong);

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int GetWindowLong (IntPtr hWnd, int nIndex);

            public static int AlterWindowStyle (Window win,
                WindowStyle orFlags, WindowStyle andNotFlags) 
            {
                var interop = new WindowInteropHelper(win);

                int prevStyle = GetWindowLong(interop.Handle, GWL_STYLE);
                if (prevStyle == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get window style");
                }

                int newStyle = (prevStyle | (int)orFlags) & ~((int)andNotFlags);
                if (SetWindowLong(interop.Handle, GWL_STYLE, newStyle) == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to set window style");
                }
                return prevStyle;
            }

            public static int DisableMaximizeButton (Window win) {
                return AlterWindowStyle(win, 0, WindowStyle.WS_MAXIMIZEBOX);
            }
        }
    }

उपयोग: यह किया जाना चाहिए स्रोत के प्रारंभ होने के बाद। एक अच्छी जगह विंडो के SourceInitialized ईवेंट का उपयोग करना है:

Window win = ...; /* the Window :-) */
WindowUtil.DisableMaximizeButton(win);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_MAXIMIZE);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_CLOSE);
while (WindowUtil.RemoveTrailingSeparator(win)) 
{
   //do it here
}

Alt + F4 कार्यक्षमता को अक्षम करने के लिए आसान तरीका सिर्फ कैंसलिंग इवेंट को वायर करना है और जब आप वास्तव में विंडो को बंद करना चाहते हैं तो इसके लिए एक ध्वज का उपयोग करें।


0

XAML कोड

<Button Command="Open" Content="_Open">
    <Button.Style>
        <Style TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Trigger>
            </Style.Triggers>
        </Style>
     </Button.Style>
</Button>

कार्य करना चाहिए

संपादित करें - आपके तात्कालिक के लिए यह थ्रेड दिखाता है कि यह कैसे किया जा सकता है, लेकिन मुझे नहीं लगता कि विंडो में एक संपत्ति है जिसे आप सामान्य शीर्षक बार खोए बिना प्राप्त करना चाहते हैं।

संपादित करें 2 यह थ्रेड इसे करने का एक तरीका दिखाता है, लेकिन आपको सिस्टम मेनू में अपनी शैली लागू करनी चाहिए और यह एक तरीका दिखाता है कि आप यह कैसे कर सकते हैं।


किसी कारण के लिए "काम करना चाहिए" बस प्रदर्शित किया गया था, लेकिन अब अपडेट हुआ है
TStamper

3
मैं विंडो स्टेट के बारे में बात कर रहा हूं, जो कि टाइटल बार में है। यह एक साधारण बटन को संपादित करने जैसा लगता है।
माइकल हेडगेथ

@ सीटीमपर, मैं आपके स्निपेट का उपयोग कैसे करूं? मैं एक वैश्विक विंडो शैली (और टेम्पलेट) का उपयोग कर रहा हूं।
शिमी वेइटहैंडलर

@ शमी- आप किसका जिक्र कर रहे हैं?
TStamper

0

विंडो में क्लोजिंग ईवेंट जोड़ने का प्रयास करें। इस कोड को ईवेंट हैंडलर में जोड़ें।

e.Cancel = true;

यह विंडो को बंद होने से रोकेगा। यह क्लोज बटन को छिपाने जैसा ही प्रभाव डालता है।


1
"यह करीब बटन को छिपाने के समान प्रभाव है।" सिवाय इसके कि बटन अभी भी दिखाई दे रहा है और क्लिक करने योग्य है, अर्थात यह एनिमेटेड है और जब आप इसे क्लिक करते हैं तो नेत्रहीन रूप से उदास हो जाता है - जो कि POLA को परिभाषित करता है
rory.ap

0

Https://stephenhaunts.com/2014/09/25/remove-the-close-button-from-a-wpf-window से संशोधित इसका उपयोग करें :

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

namespace Whatever
{
    public partial class MainMenu : Window
    {
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x00080000;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        public MainMenu()
        {
             InitializeComponent();
             this.Loaded += new RoutedEventHandler(Window_Loaded);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }  

    }
}

0

यह बटन को छिपाता नहीं है, लेकिन उपयोगकर्ता को विंडो बंद करके आगे बढ़ने से रोकेगा।

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{            
    if (e.Cancel == false)
    {
        Application.Current.Shutdown();
    }
}

-1

गोटो खिड़की गुण सेट

window style = none;

यू नॉट क्लोज़ बटन ...


Downvote। यह वास्तव में है WindowStyle = "None"- अपना सिंटैक्स देखें। दूसरे के लिए, यह एक शॉटगन दृष्टिकोण है जो टाइटल बार को भी हटा देता है, बॉक्स को बदसूरत बना देता है और एक शीर्षक की कमी होती है, जब इसे संभालने के लिए बहुत सारे बेहतर तरीके होते हैं (जैसा कि अन्य उत्तरों से पता चलता है), और एक डुप्लिकेट उत्तर है।
vapcguy

-1

जैसा कि अन्य उत्तरों में कहा गया है, आप WindowStyle="None"शीर्षक बार को पूरी तरह से हटाने के लिए उपयोग कर सकते हैं ।

और, जैसा कि उन अन्य उत्तरों की टिप्पणियों में कहा गया है, यह खिड़की को खींचने योग्य होने से रोकता है, इसलिए इसे अपनी प्रारंभिक स्थिति से स्थानांतरित करना मुश्किल है।

हालाँकि, आप विंडो के कोड बिहाइंड फ़ाइल में कंस्ट्रक्टर में कोड की एक पंक्ति जोड़कर इसे दूर कर सकते हैं:

MouseDown += delegate { DragMove(); };

या, यदि आप लैम्ब्डा सिंटैक्स पसंद करते हैं:

MouseDown += (sender, args) => DragMove();

यह संपूर्ण विंडो को ड्रैग करने योग्य बनाता है। विंडो में मौजूद कोई भी इंटरेक्टिव कंट्रोल, जैसे कि बटन, अभी भी सामान्य की तरह काम करेगा और विंडो के लिए ड्रैग-हैंडल की तरह काम नहीं करेगा।


फिर भी एक बुरा विचार। यह पूरे टाइटल बार को हटा देता है, जिससे यह शॉटगन दृष्टिकोण बन जाता है, और बॉक्स को बदसूरत बना देता है और इसका अर्थ है कि इसके लिए कोई शीर्षक / विवरण नहीं है। बहुत बेहतर विकल्प हैं।
vapcguy

@vapcguy यह पूरे शीर्षक बार को हटा देता है। यह एक बन्दूक दृष्टिकोण है। बॉक्स बदसूरत लग रहा है? आपकी राय। ज्यादा बेहतर विकल्प? आपके लिए, शायद। हर किसी के लिए नहीं। :-)
Holf

-1

इसके उत्तर की बहुत खोज करने के बाद, मैंने इस सरल समाधान को काम किया, जिसे मैं यहाँ साझा करता हूँ आशा करता हूँ कि यह दूसरों की मदद करेगा।

मैंने सेट किया WindowStyle=0x10000000

यह सेट WS_VISIBLE (0x10000000)और WS_OVERLAPPED (0x0)विंडो शैली के लिए मान। टाइटल बार और विंडो बॉर्डर दिखाने के लिए "ओवरलैप्ड" आवश्यक मूल्य है। को हटाने के द्वारा WS_MINIMIZEBOX (0x20000), WS_MAXIMIZEBOX (0x10000)और WS_SYSMENU (0x80000)मेरी शैली मूल्य से मूल्यों, शीर्षक पट्टी से सभी बटन बंद करें बटन सहित हटा दिया गया,।


डब्लूपीएफ WindowStyleएक गणना है जिसका मान विंडोज एपीआई स्थिरांक से मेल नहीं खाता है; WindowStyleगणना करने के लिए मान को काम नहीं करेगा। सुनिश्चित करने के लिए, मैंने ILSpy में .NET स्रोत कोड की जाँच की है; enum मान निजी फ़ंक्शन में Windows API में अनुवादित है CreateWindowStyle, और यदि फ़ंक्शन एक अज्ञात WindowStyleमान का सामना करता है , तो यह बस लागू होता है WindowStyle.None। (आंतरिक गुणों का उपयोग करने का एकमात्र तरीका होगा_Style का _StyleExउपयोग करने और प्रतिबिंब का , जिसे मैं दृढ़ता से सलाह देता हूं।)
माइक रोसॉफ्ट


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.