2012-07-28 7 views
9

मुझे WPF में मेरी कस्टम विंडो (AllowTransparency, WindowStyle = none) के साथ कोई समस्या है। DragMove() विधि अच्छी काम करती है, लेकिन जब मैं विंडो को अधिकतम करता हूं, या यह विंडोज 7 एरो स्नैप द्वारा स्वचालित रूप से अधिकतम हो जाता है, तो यह विधि बिल्कुल काम नहीं करती है। इसलिए मैं माउस ड्रैग के साथ विंडो को अनचाहे नहीं कर सकता और इसे विंडोस्टेट में वापस कर सकता हूं। सामान्य। बाएं और दाएं एयरो स्नैप अच्छा काम करता है, मैं बिना किसी समस्या के खिड़की को स्नैप और अनपैप कर सकता हूं। लेकिन जब यह अधिकतम हो गया, तो Win + Down संयोजन को छोड़कर कुछ भी काम नहीं करता है। हो सकता है कि कोई इस समस्या को हल करने के बारे में जानता है या मैं एरो स्नैप सुविधाओं के साथ कस्टम विंडो के उचित ड्रैगमोव को अन्य तरीके कहां से ढूंढ सकता हूं?DragMove() और अधिकतम

उत्तर

12

यहां मेरी विधि है। बनाने का प्रयास करें इसे कम)))

private void InitHeader() 
{ 
    var border = Find<Border>("borderHeader"); 
    var restoreIfMove = false; 

    border.MouseLeftButtonDown += (s, e) => 
    { 
     if (e.ClickCount == 2) 
     { 
      if ((ResizeMode == ResizeMode.CanResize) || 
       (ResizeMode == ResizeMode.CanResizeWithGrip)) 
      { 
       SwitchState(); 
      } 
     } 
     else 
     { 
      if (WindowState == WindowState.Maximized) 
      { 
       restoreIfMove = true; 
      } 

      DragMove(); 
     } 
    }; 
    border.MouseLeftButtonUp += (s, e) => 
    { 
     restoreIfMove = false; 
    }; 
    border.MouseMove += (s, e) => 
    { 
     if (restoreIfMove) 
     { 
      restoreIfMove = false; 
      var mouseX = e.GetPosition(this).X; 
      var width = RestoreBounds.Width; 
      var x = mouseX - width/2; 

      if (x < 0) 
      { 
       x = 0; 
      } 
      else 
      if (x + width > screenSize.X) 
      { 
       x = screenSize.X - width; 
      } 

      WindowState = WindowState.Normal; 
      Left = x; 
      Top = 0; 
      DragMove(); 
     } 
    }; 
} 

private void SwitchState() 
{ 
    switch (WindowState) 
    { 
     case WindowState.Normal: 
     { 
      WindowState = WindowState.Maximized; 
      break; 
     } 
     case WindowState.Maximized: 
     { 
      WindowState = WindowState.Normal; 
      break; 
     } 
    } 
} 

(screenSize प्राप्त करने के लिए मैं देशी तरीकों का उपयोग)

+0

बहुत बढ़िया! आपका बहुत बहुत धन्यवाद! –

+0

@groaner क्या आप स्क्रीनसाइज मूल विधि का उपयोग कर सकते हैं जिसका आपने उपयोग किया था? – egfconnor

9

Groaner के समाधान एकाधिक मॉनिटर सेटअप के साथ ठीक ढंग से काम नहीं करता है, विशेष रूप से जहां प्राथमिक मॉनीटर सबसे बाईं ओर नहीं है।

यहां मेरा समाधान है जो एकल या एकाधिक मॉनीटर सेटअप को ठीक से संभालता है। इस कोड में 'rctHeader' XAML में परिभाषित एक आयताकार है।

private bool mRestoreIfMove = false; 


    public MainWindow() 
    { 
     InitializeComponent(); 
    } 


    private void SwitchWindowState() 
    { 
     switch (WindowState) 
     { 
      case WindowState.Normal: 
       { 
        WindowState = WindowState.Maximized; 
        break; 
       } 
      case WindowState.Maximized: 
       { 
        WindowState = WindowState.Normal; 
        break; 
       } 
     } 
    } 


    private void rctHeader_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     if (e.ClickCount == 2) 
     { 
      if ((ResizeMode == ResizeMode.CanResize) || (ResizeMode == ResizeMode.CanResizeWithGrip)) 
      { 
       SwitchWindowState(); 
      } 

      return; 
     } 

     else if (WindowState == WindowState.Maximized) 
     { 
      mRestoreIfMove = true; 
      return; 
     } 

     DragMove(); 
    } 


    private void rctHeader_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     mRestoreIfMove = false; 
    } 


    private void rctHeader_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (mRestoreIfMove) 
     { 
      mRestoreIfMove = false; 

      double percentHorizontal = e.GetPosition(this).X/ActualWidth; 
      double targetHorizontal = RestoreBounds.Width * percentHorizontal; 

      double percentVertical = e.GetPosition(this).Y/ActualHeight; 
      double targetVertical = RestoreBounds.Height * percentVertical; 

      WindowState = WindowState.Normal; 

      POINT lMousePosition; 
      GetCursorPos(out lMousePosition); 

      Left = lMousePosition.X - targetHorizontal; 
      Top = lMousePosition.Y - targetVertical; 

      DragMove(); 
     } 
    } 



    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool GetCursorPos(out POINT lpPoint); 


    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
     public int X; 
     public int Y; 

     public POINT(int x, int y) 
     { 
      this.X = x; 
      this.Y = y; 
     } 
    } 


} 
0

मैं इस पर एक ब्लॉग पोस्ट में लिखा है:

http://dragablz.net/2014/12/16/getting-windows-snap-to-play-with-wpf-borderless-windows/

+1

मुझे खेद है लेकिन ब्लॉग पोस्ट लगभग बेकार है, इसे वास्तव में ब्लॉग पोस्ट में उल्लिखित संपूर्ण परियोजना को अलग करने और आवश्यकतानुसार बाहर निकलने की आवश्यकता है। – CularBytes

4

WPF में मैं अत्यधिक है जब आपके Window.DragMove से पहले खिड़की बहाल Control.PointToScreen का उपयोग कर की सिफारिश करेंगे। प्वाइंटटस्क्रीन कई मॉनीटर सेटअप भी संभाल लेंगे। यह निम्न को पुनर्स्थापित करने के लिए आसान करेगा:

private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     if(e.ClickCount == 2) 
     { 
      if(ResizeMode != ResizeMode.CanResize && 
       ResizeMode != ResizeMode.CanResizeWithGrip) 
      { 
       return; 
      } 

      WindowState = WindowState == WindowState.Maximized 
       ? WindowState.Normal 
       : WindowState.Maximized; 
     } 
     else 
     { 
      mRestoreForDragMove = WindowState == WindowState.Maximized; 
      DragMove(); 
     } 
    } 

    private void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if(mRestoreForDragMove) 
     { 
      mRestoreForDragMove = false; 

      var point = PointToScreen(e.MouseDevice.GetPosition(this)); 

      Left = point.X - (RestoreBounds.Width * 0.5); 
      Top = point.Y; 

      WindowState = WindowState.Normal; 

      DragMove(); 
     } 
    } 

    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     mRestoreForDragMove = false; 
    } 

    private bool mRestoreForDragMove; 
+0

यह समाधान पूरी तरह से काम करता है, ठीक वही जो मैं खोज रहा था। साझा करने के लिए धन्यवाद। – Al0x

+0

अन्य समाधानों की तुलना में यह सबसे अच्छा काम कर रहा है - इसमें इसकी मामूली खामियां हैं लेकिन यह वास्तव में अच्छी तरह से काम करती है। –

2

एक और उत्तर के लिए थोड़ा देर हो चुकी है, लेकिन मेरा कोड सरल था इसलिए मैं इसे यहां रखूंगा। जैसे ही आप बाएं और दाएं स्नैपिंग पुरुषों को ठीक काम करते हैं, लेकिन जब विंडो को अधिकतम किया जाता है या ऊपरी स्क्रीन सीमाओं को स्नैप करता है और अधिकतम करता है, तो ड्रैगमोव विधि काम नहीं करेगी!


बस तत्व आप इस तरह के साथ खींचना चाहते हैं पर Mouse_Down घटना संभाल:

private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    if (WindowState == WindowState.Maximized) 
    { 
     var point = PointToScreen(e.MouseDevice.GetPosition(this)); 

     if (point.X <= RestoreBounds.Width/2) 
      Left = 0; 

     else if (point.X >= RestoreBounds.Width) 
      Left = point.X - (RestoreBounds.Width - (this.ActualWidth - point.X)); 

     else 
      Left = point.X - (RestoreBounds.Width/2); 

     Top = point.Y - (((FrameworkElement)sender).ActualHeight/2); 
     WindowState = WindowState.Normal; 
    } 
    DragMove(); 
} 

मुझे आशा है कि यह किसी को मदद करता है!

+0

औपचारिक रूप से ऐसा होता है कि खिड़की एक सामान्य स्थिति में वापस आती है लेकिन माउस को एंकर नहीं करती जो वास्तव में परेशान होती है। –

संबंधित मुद्दे