एक सीमा के बिना एक WPF विंडो कैसे बनाएं जिसे केवल एक पकड़ के माध्यम से आकार दिया जा सकता है?


94

यदि आप ResizeMode="CanResizeWithGrip"एक WPF पर सेट करते हैं Windowतो नीचे दायें कोने में एक रिसाइज ग्रिप दिखाई जाती है:

यदि आप WindowStyle="None"टाइटल बार सेट करते हैं तो गायब हो जाता है लेकिन ग्रे बेवेल्ड एज तब तक रहता है जब तक आप सेट नहीं करते ResizeMode="NoResize"। दुर्भाग्य से, गुणों के इस संयोजन के साथ, रिसाइज़ ग्रिप भी गायब हो जाती है।

मैं अधिरोहित है Windowकी ControlTemplateएक कस्टम के माध्यम से Style। मैं स्वयं विंडो की सीमा निर्दिष्ट करना चाहता हूं, और मुझे उपयोगकर्ताओं को सभी चार तरफ से विंडो को आकार देने में सक्षम होने की आवश्यकता नहीं है, लेकिन मुझे आकार बदलने की आवश्यकता है।

क्या कोई इन सभी मानदंडों को पूरा करने का एक सरल तरीका बता सकता है?

  1. Windowमैं खुद में निर्दिष्ट एक से अलग पर एक सीमा नहीं है ControlTemplate
  2. करो निचले दाएँ कोने में एक काम आकार पकड़ है।
  3. टाइटल बार नहीं है।

3
कृपया ध्यान दें कि Allowtransperency मेमोरी लीक बनाता है। इसलिए इसके इस्तेमाल से बचें। कृपया social.msdn.microsoft.com/Forums/en/wpf/thread/…
दीपेश भट्ट

1
@DipeshBhatt मुझे आपके द्वारा दिए गए लिंक में उस दावे का कोई स्पष्टीकरण नहीं मिला। शायद आप लिंक social.msdn.microsoft.com/Forums/vstudio/en-US/…
इसके लिए

मैं शीर्ष पर ग्रे एज का सामना कर रहा था, हालांकि मैंने विंडो स्टाइल को किसी को भी सेट नहीं किया था। ResizeMode = "NoResize" ने मेरी समस्या हल कर दी।
सुरेन्द्र श्रेष्ठ

जवाबों:


180

यदि आप AllowsTransparencyसंपत्ति को Window(यहां तक ​​कि किसी भी पारदर्शिता मूल्यों को निर्धारित किए बिना) सेट करते हैं , तो सीमा गायब हो जाती है और आप केवल पकड़ के माध्यम से आकार बदल सकते हैं।

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640" Height="480" 
    WindowStyle="None"
    AllowsTransparency="True"
    ResizeMode="CanResizeWithGrip">

    <!-- Content -->

</Window>

परिणाम जैसा दिखता है:


शुद्ध अस्थायी मुझे यह पता था - मैं आज दोपहर को उसी नियंत्रण के साथ खेल रहा था। :)
ज़ोंबीशेप

2
वाह, मैं यह उम्मीद नहीं करूँगा, लेकिन यह आपके-आपके-पोस्ट-इट-नोट्स-इन-5-मिनटों के लिए पूरी तरह से काम करता है, धन्यवाद :)
Tomáš Kafka

4
AllowTransparency में कई कमियां हैं, हालांकि Windows अब उप विंडो नियंत्रण की मेजबानी नहीं कर सकता है जैसे कि WebBrowser, आमतौर पर सॉफ्टवेयर रेंडरिंग को मजबूर करता है, स्मृति लीक की सूचना दी है। नीचे मेरा समाधान देखें।
वॉबल्स

सीमाओं से छुटकारा पाने के लिए आपको केवल WindowStyle = "कोई नहीं" चाहिए; AllowTransparency केवल इसकी आवश्यकता होती है, लेकिन सीमाओं को प्रभावित नहीं करता है ..
'18:

2
@Grault thats खिड़की के हेडर से छुटकारा पा लेता है, लेकिन अभी भी फॉर्म के चारों ओर एक ठोस सीमा है। AllowTransparency सीमाओं से छुटकारा दिलाता है।
वोबेल्स

79

मैं एक सीमा-विहीन खिड़की बनाने की कोशिश कर रहा था, WindowStyle="None"लेकिन जब मैंने इसका परीक्षण किया, तो लगता है कि शीर्ष में एक सफेद पट्टी दिखाई देती है, कुछ शोधों के बाद यह "आकार सीमा" प्रतीत होती है, यहां एक छवि है (मैंने पीले रंग में टिप्पणी की):

चुनौती

इंटरनेट पर कुछ शोध के बाद, और बहुत सारे कठिन गैर xaml समाधान, मेरे द्वारा पाए गए सभी समाधान C # में कोड के पीछे और कोड लाइनों के बहुत सारे थे, मुझे अप्रत्यक्ष रूप से यहां समाधान मिला: अधिकतम कस्टम विंडो ड्रॉप शैडो इफेक्ट खो देता है

<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

नोट : आपको .NET 4.5 फ्रेमवर्क का उपयोग करने की आवश्यकता है, या यदि आप पुराने संस्करण का उपयोग कर रहे हैं WPFShell का उपयोग करें, बस शेल का संदर्भ लें और Shell:WindowChrome.WindowChromeइसके बजाय उपयोग करें ।

मैंने WindowChromeविंडो की संपत्ति का उपयोग किया , यदि आप इसका उपयोग करते हैं कि सफेद "बॉर्डर का आकार" गायब हो जाता है, लेकिन आपको सही ढंग से काम करने के लिए कुछ गुणों को परिभाषित करने की आवश्यकता है।

कैप्शनहाइट: यह कैप्शन क्षेत्र (हेडरबार) की ऊंचाई है जो एयरो स्नैप के लिए अनुमति देता है, एक सामान्य शीर्षक बार के रूप में डबल क्लिक व्यवहार करता है। बटन को काम करने के लिए इसे 0 (शून्य) पर सेट करें।

ResizeBorderThickness: यह विंडो के किनारे पर मोटाई है जो कि आप विंडो का आकार बदल सकते हैं। मैं 5 को डालता हूं क्योंकि मुझे वह संख्या पसंद है, और क्योंकि अगर आपने खिड़की को आकार देने के लिए शून्य को रखा है।

इस छोटे कोड का उपयोग करने के बाद परिणाम यह है:

समाधान

और अब, सफेद सीमा का उपयोग किए बिना गायब हो गया ResizeMode="NoResize"और AllowsTransparency="True", यह भी खिड़की में एक छाया दिखाता है।

बाद में मैं समझाऊंगा कि कैसे बटन बनाने के लिए (मैंने बटन के लिए छवियों का उपयोग नहीं किया है) सरल और संक्षिप्त कोड के साथ आसानी से, Im नया और मुझे लगता है कि मैं कोडप्रोजेक्ट में पोस्ट कर सकता हूं, क्योंकि यहां मुझे जगह नहीं मिली ट्यूटोरियल पोस्ट करने के लिए।

शायद एक और समाधान है (मुझे पता है कि मेरे जैसे नोज के लिए कठिन और कठिन समाधान हैं) लेकिन यह मेरी व्यक्तिगत परियोजनाओं के लिए काम करता है।

यहाँ पूरा कोड है

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Concursos"
    mc:Ignorable="d"
    Title="Concuros" Height="350" Width="525"
    WindowStyle="None"
    WindowState="Normal" 
    ResizeMode="CanResize"
    >
<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

    <Grid>

    <Rectangle Fill="#D53736" HorizontalAlignment="Stretch" Height="35" VerticalAlignment="Top" PreviewMouseDown="Rectangle_PreviewMouseDown" />
    <Button x:Name="Btnclose" Content="r" HorizontalAlignment="Right" VerticalAlignment="Top" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmax" Content="2" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,35,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmin" Content="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,70,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>

</Grid>

धन्यवाद!


3
खैर, इस एक के लिए यश! यह अब तक का सबसे सरल / कोई ट्रेड नहीं है जो इस धागे के उत्तर को बंद करता है! बहुत अधिक 'वोट' मिलना चाहिए। मुझे यह स्वीकार करना होगा कि मैं इसके बारे में सेप्टिक था, खासकर हुड के नीचे क्या हो रहा था। मैंने डब्ल्यूएफपी पेड़ की भी जाँच की और यह सुनिश्चित हुआ कि पारदर्शिता वापस नहीं जुड़ती है। यहां तक ​​कि 'वेबब्रोसर' डिस्प्ले जैसे ट्रिकी कंट्रोल भी ठीक हैं। जब एप्लिकेशन बहुत अधिक तनाव में था, तब मैंने पारदर्शिता का उपयोग करते हुए एक रेंडरिंग फ्रीजिंग मुद्दा दिया था ... खैर, इस समाधान के साथ ऐसा नहीं हो रहा है। मुझे लगता है कि यह रिटायर होने का समय हो सकता है!
वीवी

1
यदि मुझे Rectangle_PreviewMouseDownघटना के उपयोग की सही व्याख्या करनी हो तो ऐसा लगता है कि खिड़की को खींचने के लिए अभी भी इंटरोप की आवश्यकता हो सकती है।
wobbles

यह <= विन 8.1 में काम नहीं कर सकता है, मेरे वीएम में कुछ विषम परिणाम देखे गए। विंडोज 7 और 8 प्राथमिक चिंताएं हैं क्योंकि वे बेवकूफ एयरो बॉर्डर की बात करते हैं।
वॉबल्स

आपके उत्तर के लिए धन्यवाद
फर्नांडो एगुइरे

हाय @FernandoAguirre, मैंने इस संबंधित प्रश्न को पोस्ट किया है , और यदि आपके पास कोई उत्तर है तो आभारी होंगे।
संपतश्री 14

40

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

हालांकि आसपास बेहतर काम है।

जब आप बिना सीमा के साथ एक विंडो बनाना चाहते हैं जो कि रहने योग्य है और एक WebBrowser नियंत्रण या फ़्रेम कंट्रोल को होस्ट करने में सक्षम है, जो आपके द्वारा आसानी से नहीं किया जा सकता है, तो उक्त नियंत्रण की सामग्री खाली दिखाई देगी।

मुझे एक समाधान मिला; विंडो में, यदि आप WindowStyle को कोई भी सेट नहीं करते हैं, तो ResizeMode to NoResize (मेरे साथ सहन करें, आप अभी भी एक बार आकार बदलने में सक्षम होंगे) तो सुनिश्चित करें कि आपके पास UNCHECKED AllowTransparency है, जिसमें आपके पास बिना बॉर्डर वाली एक स्थिर आकार की विंडो होगी और दिखाई देगी ब्राउज़र नियंत्रण।

अब, आप अभी भी सही का आकार बदलने में सक्षम होना चाहते हैं? वैसे हम एक इंटरोप कॉल के साथ कर सकते हैं:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    //Attach this to the MouseDown event of your drag control to move the window in place of the title bar
    private void WindowDrag(object sender, MouseButtonEventArgs e) // MouseDown
    {
        ReleaseCapture();
        SendMessage(new WindowInteropHelper(this).Handle,
            0xA1, (IntPtr)0x2, (IntPtr)0);
    }

    //Attach this to the PreviewMousLeftButtonDown event of the grip control in the lower right corner of the form to resize the window
    private void WindowResize(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
    {
        HwndSource hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
        SendMessage(hwndSource.Handle, 0x112, (IntPtr)61448, IntPtr.Zero);
    }

और वोइला, एक WPF विंडो जिसमें कोई बॉर्डर नहीं है और फिर भी वेबब्रोसर जैसे नियंत्रणों के साथ संगतता खोने के बिना चल और resizable है


यदि हम सभी पक्षों से आकार लेना चाहते हैं, तो न केवल नीचे की ओर, बल्कि फिर भी कोई सीमा नहीं दिखनी चाहिए?
डैनियल

6
यहाँ अन्य wParam मान हैं, बस जरूरत के अनुसार इनका उपयोग करके नई UI ऑब्जेक्ट्स को नई ईवेंट असाइन करेंprivate enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
Wobbles

यह मेरे लिए बहुत अच्छा काम करता है, एक अपवाद के साथ, हालांकि एक बार आपके पास NoResize होने के बाद आप इसे शीर्ष पर खींचकर विंडो को स्नैप नहीं कर सकते।
CJK

2
@CJK ट्रू, लेकिन इसमें कोई शक नहीं कि आप विंडोज़ संदेशों को उस तरह से हुक कर सकते हैं और उसे संभाल सकते हैं।
wobbles

मैं खिड़की नहीं खींच सकता। किसी भी विचार क्यों? (एक आकर्षण की तरह काम करता है का आकार बदलें)
Li3ro

5

यहाँ नमूना:

<Style TargetType="Window" x:Key="DialogWindow">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Border BorderBrush="Black" BorderThickness="3" CornerRadius="10" Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" Background="Gray">
                        <DockPanel>
                            <Grid DockPanel.Dock="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition></ColumnDefinition>
                                    <ColumnDefinition Width="50"/>
                                </Grid.ColumnDefinitions>
                                <Label Height="35" Grid.ColumnSpan="2"
                                       x:Name="PART_WindowHeader"                                            
                                       HorizontalAlignment="Stretch" 
                                       VerticalAlignment="Stretch"/>
                                <Button Width="15" Height="15" Content="x" Grid.Column="1" x:Name="PART_CloseButton"/>
                            </Grid>
                            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                                        Background="LightBlue" CornerRadius="0,0,10,10" 
                                        Grid.ColumnSpan="2"
                                        Grid.RowSpan="2">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition Width="20"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*"/>
                                        <RowDefinition Height="20"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <ResizeGrip Width="10" Height="10" Grid.Column="1" VerticalAlignment="Bottom" Grid.Row="1"/>
                                </Grid>
                            </Border>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

23
आपको एक संक्षिप्त विवरण शामिल करना चाहिए कि कोड कैसे काम करता है।
M456

0

मुझे WindowChromeकाम करने के लिए @ fernando-aguirre द्वारा उत्तर प्राप्त करने में कठिनाई हो रही थी । यह मेरे मामले में काम नहीं कर रहा था क्योंकि मैं बेस क्लास मेथड OnSourceInitializedमें ओवरराइड कर रहा था MainWindowऔर कॉल नहीं कर रहा था ।

protected override void OnSourceInitialized(EventArgs e)
{
    ViewModel.Initialize(this);
    base.OnSourceInitialized(e); // <== Need to call this!
}

इसने मुझे बहुत लंबे समय तक स्टंप किया।

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