【问题标题】:How to create a non rectangular form?如何创建非矩形形式?
【发布时间】:2014-11-03 02:38:27
【问题描述】:

c# 中是否有任何类型的窗口、表单或任何看起来不像通常的表单或对话框并且可以包含标签等组件的东西?类似于这张图片上的黑色矩形:

我还需要当您单击ControlBox 时,这个“窗口”可以像表单一样移动,但只需在它的任何位置按住鼠标即可。但是,它(或至少它的背景)在某些级别(高、中、低透明度)中应该具有类似透明度的属性。

我应该使用什么?

谢谢。

【问题讨论】:

  • 没有边界的表格?
  • 您可以修改 winforms 表单的外观,使其看起来像您想要的那样。从技术上讲,这与 C# 完全无关。您需要具体说明您要询问的框架是 Winforms 还是 WPF?
  • @TheMuffinMan “form”这个词的使用表明他在谈论 Windows 窗体,但它含糊不清。
  • 听起来像一个小工具

标签: c# winforms


【解决方案1】:

您可以在 WinForms Form 中通过将BackgroundImage 属性设置为适当的位图来实现此目的。例如:

然后,将表单的FormBorderStyle 设置为None,并将TransparencyKey 设置为位图中必须透明的颜色(本例中为Color.Red)。就是这样!

您将无法拥有部分透明的区域;但是,您可以设置表单的整体Opacity(= 100% - 透明度)。

还要注意,由于您不再有标题栏(因为FormBorderStyle = None),您将无法使用关闭按钮关闭表单并将窗口移动拖动标题栏。您必须通过处理鼠标或按键事件自己处理这些事情。

当然,您可以像往常一样在此表单上放置任何类型的控件。

【讨论】:

    【解决方案2】:

    如果您需要完整的表单级功能,解决此问题的一种方法是制作一个 FormBorderStyle = None 的表单。这会从表单中移除整个边框,它只会显示为一个扁平的矩形,具有您放置在那里的任何背景颜色。

    这有几个问题:

    1. 除非您实现某种点击处理程序以允许在屏幕上拖动它,否则用户将无法移动它。
    2. 用户必须使用任务栏(假设您将其保留在那里)或 Alt-F4 来关闭窗口。

    根据您关于如何解决 #2 的问题,How to drag a borderless Windows Form by mouse 上有一个 SO 页面。万一它很快被删除,我将复制 Joey 的代码(基于链接的文章):

    // DllImportAttribute requires reference to System.Runtime.InteropServices
    
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    
    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();
    
    public Form1()
    {
        InitializeComponent();
    }
    
    private void Form1_MouseDown_1(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }
    }
    

    请注意,我没有做任何测试,只是将其粘贴并验证,是的,您可以用鼠标在其内容区域内拖动您的表单。另请注意,此拖动操作仅适用于表单的空白区域 - 如果您的鼠标悬停在表单的某个控件上,您将无法拖动它。

    编辑:问题的标题自最初发布以来已更改 - 最初,该问题并没有专门用于如何创建 非矩形 表单以及更多关于如何创建 borderless 形式 - 但是现在问题的非矩形边界部分由下面的 Olivier Jacot-Descombes 解决。我不会窃取他的贡献,但是这两个答案的组合应该会给你你想要的。

    【讨论】:

    • 如何实现第二点?我还是个初学者(只是个学生)。
    • @Drumnbass 添加了一些可能对您有用的代码。如果对您有帮助,请不要忘记将其作为您选择的答案。
    • 老实说,我对那段代码几乎一无所知(为什么需要 dll 导入,什么是(或表示)这些常量),但它绝对有效。我真的很想理解它(我根本不是一个循规蹈矩的人),但我认为你已经做了足够的帮助我,只有当你有时间、知识并且能够通过简单的方式向我解释方式,我会非常感激;D
    • @Drumnbass 我对 .NET 互操作性并不十分精通,但 Form1_MouseDown_1 代码本质上是向 Windows 发送与移动窗口时 .NET 通常会发送的相同类型的消息 -本质上只是告诉它“现在正在拖动窗体的边框,用鼠标移动窗体”,即使它实际上并不是被拖动的边框。任何比这更技术/更具体的事情都超出了我的范围。
    • 附加信息:如果我将其(控制)MouseDown 事件订阅到您给我的Form1_MouseDown_1 方法,我似乎仍然可以移动表单,如果鼠标悬停在任何控件上;D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 2011-06-05
    • 1970-01-01
    • 2013-07-11
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多