当前位置: 首页 > 编程日记 > 正文

使用.NET自带的类实现DataGrid报表的打印。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Printing;
using System.Data;
using System.Collections;
using DataLibrary;

namespace ControlLibrary
{
 /// <summary>
 /// DataGrid打印
 /// </summary>
 public class DataGridPrinter
 {
  private PrintDocument ThePrintDocument;
  private DataTable TheTable;
  private DataGrid  TheDataGrid;
  public int RowCount = 0;
  private const int kVerticalCellLeeway = 10;
  public int PageNumber = 1;
  public ArrayList Lines = new ArrayList();
  public int header=0;
  public int footer=0;
  DataCatena DataCatena1;
  public int PageWidth;
  public int PageHeight;
  public int TopMargin;
  public int BottomMargin;
  int GridWidth = 0;
  public int LeftMargin;
  public int RightMargin;
  public string PaperName;
  public int pagecount;
  private int rows_page;
  public bool showfooter;

public int bodylength
  {
   get
   {
    if(this.PageNumber<this.pagecount)
     return (1+this.rows_page) * ((int)(TheDataGrid.Font.SizeInPoints)  + kVerticalCellLeeway);
    else
     return (this.TheTable.Rows.Count + 1 -(this.rows_page*(this.PageNumber-1))) * ( (int)(TheDataGrid.Font.SizeInPoints)  + kVerticalCellLeeway);
   }
  }

public DataGridPrinter(DataGrid aGrid, PrintDocument aPrintDocument,string theform,int Header,int Footer)
  {
   //
   // TODO: Add constructor logic here
   //
   this.header=Header;
   this.footer=Footer;
   this.showfooter=true;
   TheDataGrid = aGrid;
   ThePrintDocument = aPrintDocument;
   if(theform!="")
   {
    DataCatena1=new DataCatena();
    DataView myDV=DataCatena1.GetDataView("select * from yh_bbdy where bm='"+theform +"'");

this.PaperName=myDV[0]["zm"].ToString();

PaperSize pkSize;

if(myDV[0]["fx"].ToString()=="True")
     this.ThePrintDocument.DefaultPageSettings.Landscape=true;
    else
     this.ThePrintDocument.DefaultPageSettings.Landscape=false;

int found=0;
    for (int i = 0; i < this.ThePrintDocument.PrinterSettings.PaperSizes.Count; i++)
    {
     pkSize = this.ThePrintDocument.PrinterSettings.PaperSizes[i];
     if(pkSize.PaperName==this.PaperName)
     {
      this.ThePrintDocument.DefaultPageSettings.PaperSize=pkSize;
      found=1;
      i=this.ThePrintDocument.PrinterSettings.PaperSizes.Count;
      if(this.ThePrintDocument.DefaultPageSettings.Landscape)
      {
       PageHeight = pkSize.Width;
       PageWidth = pkSize.Height;
      }
      else
      {
       PageWidth = pkSize.Width;
       PageHeight = pkSize.Height;
      }
     }
    }

if(found==0)
    {
     if(this.ThePrintDocument.DefaultPageSettings.Landscape)
     {
      PageHeight = Int32.Parse(myDV[0]["zk"].ToString());
      PageWidth = Int32.Parse(myDV[0]["zc"].ToString());
     }
     else
     {
      PageWidth = Int32.Parse(myDV[0]["zk"].ToString());
      PageHeight = Int32.Parse(myDV[0]["zc"].ToString());
     }
    }

TopMargin = Int32.Parse(myDV[0]["sk"].ToString());
    BottomMargin = Int32.Parse(myDV[0]["xk"].ToString());
    RightMargin = Int32.Parse(myDV[0]["rightk"].ToString());
    LeftMargin = Int32.Parse(myDV[0]["leftk"].ToString());
   }
   else
   {
    PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Width;
    PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Height;
    TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top;
    BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom;
    RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right;
    LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left;
   }

PageWidth -= this.LeftMargin ;
   PageWidth -= this.RightMargin;

this.rows_page=(int)((float)(this.PageHeight-this.TopMargin-this.BottomMargin-this.footer-this.header)/(TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway));

for (int k = 0; k < TheDataGrid.TableStyles[0].GridColumnStyles.Count; k++)
   {
    GridWidth += TheDataGrid.TableStyles[0].GridColumnStyles[k].Width;  //  TheTable.Columns[k].ToString();
   }

}

public void DrawHeader(Graphics g)
  {
   SolidBrush ForeBrush = new SolidBrush(TheDataGrid.HeaderForeColor);
   SolidBrush BackBrush = new SolidBrush(Color.White);   //(TheDataGrid.HeaderBackColor);
   Pen TheLinePen = new Pen(TheDataGrid.GridLineColor, 1);
   StringFormat cellformat = new StringFormat();
   cellformat.Trimming = StringTrimming.EllipsisCharacter;
   cellformat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
   cellformat.Alignment= StringAlignment.Center;


   int columnwidth = 0;

int initialRowCount = RowCount;

// draw the table header
   float startxposition = this.LeftMargin;                      //TheDataGrid.Location.X;
   RectangleF nextcellbounds = new RectangleF(0,0, 0, 0);

/*
      这一段是画表头底色的代码

RectangleF HeaderBounds  = new RectangleF(0, 0, 0, 0);

HeaderBounds.X = this.LeftMargin;       //TheDataGrid.Location.X;
      HeaderBounds.Y =  + (RowCount - initialRowCount) * (TheDataGrid.Font.SizeInPoints  + kVerticalCellLeeway);
      HeaderBounds.Height = TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway;
      HeaderBounds.Width = PageWidth;
   */
   float y1=(float)(header+this.TopMargin);

g.DrawLine(TheLinePen, this.LeftMargin, y1, this.LeftMargin + this.PageWidth, y1);
   y1=y1+ (float)(TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway);
   g.DrawLine(TheLinePen, this.LeftMargin, y1, this.LeftMargin + this.PageWidth, y1);

//   g.FillRectangle(BackBrush, HeaderBounds);

for (int k = 0; k < this.TheDataGrid.TableStyles[0].GridColumnStyles.Count; k++)
   {
    columnwidth = TheDataGrid.TableStyles[0].GridColumnStyles[k].Width * PageWidth / this.GridWidth;

string nextcolumn = TheDataGrid.TableStyles[0].GridColumnStyles[k].HeaderText;  //  TheTable.Columns[k].ToString(); + (RowCount - initialRowCount) * (TheDataGrid.Font.SizeInPoints  + kVerticalCellLeeway)
    RectangleF cellbounds = new RectangleF(startxposition, header + TopMargin+2 ,
     columnwidth,
     TheDataGrid.HeaderFont.SizeInPoints + kVerticalCellLeeway-2);
    nextcellbounds = cellbounds;

if (startxposition + columnwidth <= PageWidth+this.LeftMargin)
    {
     g.DrawString(nextcolumn, TheDataGrid.HeaderFont, ForeBrush, cellbounds, cellformat);
    }

startxposition = startxposition + columnwidth;

}
   y1=y1+ (float)(TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway);
   g.DrawLine(TheLinePen, this.LeftMargin, y1, this.LeftMargin + this.PageWidth, y1);
 
   //if (TheDataGrid.GridLineStyle != DataGridLineStyle.None)
   // g.DrawLine(TheLinePen, TheDataGrid.Location.X, nextcellbounds.Bottom, PageWidth, nextcellbounds.Bottom);
  }

public void SetDataSource(DataTable aTable)
  {
   TheTable = aTable;
   this.pagecount=(int)Math.Ceiling((double)(TheTable.Rows.Count)/(double)(this.rows_page));
   // MessageBox.Show("rows_count:"+TheTable.Rows.Count.ToString()+" rows_page:"+rows_page.ToString() + "page_count:" +this.pagecount.ToString());
   // this.ThePrintDocument
  }

public bool DrawRows(Graphics g)
  {
   int lastRowBottom = TopMargin;
   Lines.Clear();

try
   {
    SolidBrush ForeBrush = new SolidBrush(TheDataGrid.ForeColor);
    SolidBrush BackBrush = new SolidBrush(TheDataGrid.BackColor);
    SolidBrush AlternatingBackBrush = new SolidBrush(TheDataGrid.AlternatingBackColor);
    Pen TheLinePen = new Pen(TheDataGrid.GridLineColor, 1);
    StringFormat cellformat = new StringFormat();
    cellformat.Trimming = StringTrimming.EllipsisCharacter;
    cellformat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
    int columnwidth = PageWidth/TheDataGrid.TableStyles[0].GridColumnStyles.Count;

int initialRowCount = (this.PageNumber-1)*this.rows_page;
    int endrow=initialRowCount+this.rows_page;

RectangleF RowBounds  = new RectangleF(0, 0, 0, 0);

// draw vertical lines

// draw the rows of the table
    for (int i = initialRowCount; i < TheTable.Rows.Count && i< endrow; i++)
    {
     DataRow dr = TheTable.Rows[i];
     int startxposition = this.LeftMargin+2;      //TheDataGrid.Location.X;

RowBounds.X = 0;
     RowBounds.Y = header + TopMargin + ((RowCount - initialRowCount)+1) * (TheDataGrid.Font.SizeInPoints  + kVerticalCellLeeway);
     RowBounds.Height = TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway;
     RowBounds.Width = PageWidth;


     /*  ///这一段是画表格底色的代码
          if (i%2 == 0)
          {
           g.FillRectangle(BackBrush, RowBounds);
          }
          else
          {
           g.FillRectangle(AlternatingBackBrush, RowBounds);
          }
     */

for (int j = 0; j < TheDataGrid.TableStyles[0].GridColumnStyles.Count; j++)
     {
      columnwidth = TheDataGrid.TableStyles[0].GridColumnStyles[j].Width* PageWidth / this.GridWidth -2;
      RectangleF cellbounds = new RectangleF(startxposition,
       header + TopMargin + 2 +
       ((RowCount - initialRowCount) + 1) * (TheDataGrid.Font.SizeInPoints  + kVerticalCellLeeway),
       columnwidth,
       TheDataGrid.Font.SizeInPoints + kVerticalCellLeeway);

if (startxposition + columnwidth <= PageWidth)
      {
       g.DrawString(dr[(TheDataGrid.TableStyles[0].GridColumnStyles[j].MappingName)].ToString(), TheDataGrid.Font, ForeBrush, cellbounds, cellformat);
      }

startxposition = startxposition + columnwidth+2;
     }

Lines.Add(RowBounds.Bottom);
     lastRowBottom = (int)RowBounds.Bottom;

RowCount++;
    }

DrawHorizontalLines(g, Lines);
    DrawVerticalGridLines(g, TheLinePen,lastRowBottom);
    
    if(this.showfooter==true)
     DrawFooter(g);

if (this.PageNumber<this.pagecount)
    {
     return true;
    }
    else
    {
     return false;
    }

}
   catch (Exception ex)
   {
    MessageBox.Show(ex.Message.ToString());

return false;
   }

}

void DrawFooter(Graphics g)
  {
   FontFamily fontFamily = new FontFamily("宋体");

string text="第"+this.PageNumber.ToString()+"页 共"
    +this.pagecount.ToString()+"页";

Font font = new Font(
    fontFamily, 10,
    FontStyle.Regular,
    GraphicsUnit.Point);

SizeF size= g.MeasureString(text,font);

int startpos = this.PageHeight
    -this.BottomMargin;

SolidBrush ForeBrush = new SolidBrush(Color.Black);

StringFormat cellformat = new StringFormat();

g.DrawString(text,font,ForeBrush,
    (this.PageWidth-size.Width)/2 + this.LeftMargin,
    startpos, cellformat);

text="【Cobainsoft】";

size= g.MeasureString(text,font);

g.DrawString(text,font,ForeBrush,
    this.PageWidth + this.LeftMargin - size.Width-3,
    startpos, cellformat);

}

void DrawHorizontalLines(Graphics g, ArrayList lines)
  {
   Pen TheLinePen = new Pen(TheDataGrid.GridLineColor, 1);

if (TheDataGrid.GridLineStyle == DataGridLineStyle.None)
    return;

int i;

for (i = 0;  i < lines.Count; i++)
   {
    g.DrawLine(TheLinePen, this.LeftMargin, (float)lines[i], this.LeftMargin + this.PageWidth, (float)lines[i]);
   }

}

void DrawVerticalGridLines(Graphics g, Pen TheLinePen, int bottom)
  {
   if (TheDataGrid.GridLineStyle == DataGridLineStyle.None)
    return;

int posx=0;

//画最左边的竖线

g.DrawLine(TheLinePen, this.LeftMargin + posx,
    header + TopMargin,
    this.LeftMargin + posx,
    bottom);

//画最右边的竖线
   g.DrawLine(TheLinePen, this.LeftMargin + this.PageWidth,
    header + TopMargin,
    this.LeftMargin + this.PageWidth,
    bottom);

int total=TheDataGrid.TableStyles[0].GridColumnStyles.Count -1;
   for (int k = 0; k < total; k++)
   {
    posx+=(TheDataGrid.TableStyles[0].GridColumnStyles[k].Width) * this.PageWidth / this.GridWidth;
    g.DrawLine(TheLinePen, this.LeftMargin + posx,
     header + TopMargin,
     this.LeftMargin + posx,
     bottom);
   }
  }


  public bool DrawDataGrid(Graphics g)
  {

try
   {
    DrawHeader(g);
    bool bContinue = DrawRows(g);
    return bContinue;
   }
   catch (Exception ex)
   {
    MessageBox.Show(ex.Message.ToString());
    return false;
   }

}

}

}

相关文章:

各种 AI 数据增强方法,都在这儿了

来源 | 算法进阶责编 | 寇雪芹头图 | 下载于视觉中国数据、算法、算力是人工智能发展的三要素。数据决定了Ai模型学习的上限&#xff0c;数据规模越大、质量越高&#xff0c;模型就能够拥有更好的泛化能力。然而在实际工程中&#xff0c;经常有数据量太少(相对模型而言)、样本不…

ORACLE11g 前期安装环境配置

Linux系统可以拿来直接用的脚本哦#!/bin/bashservice iptables stop &> /dev/nulliptables -F service iptables save &> /dev/nullsed -i s/enforcing/disabled/ /etc/selinux/configsetenforce 0sed /tmpfs/d /etc/fstab &> /dev/nullecho tmpfs …

linux mysql 卸载,安装,測试全过程

Mysql卸载yum remove mysql mysql-server mysql-libs compat-mysql51rm -rf /var/lib/mysqlrm /etc/my.cnf查看是否还有mysql软件&#xff1a;rpm -qa|grep mysql有的话继续删除Mysql安装1>若本地没有安装包 能够考虑使用yum命令进行下载# yum -y install mysql-server# yum…

C#中获取程序当前路径的集中方法

string str1 Process.GetCurrentProcess().MainModule.FileName;//可获得当前执行的exe的文件名。 string str2Environment.CurrentDirectory;//获取和设置当前目录&#xff08;即该进程从中启动的目录&#xff09;的完全限定路径。//备注 按照定义&#xff0c;如果该进程在本…

如何开启远程(win7win8)

如何开启远程连接点击我的电脑-属性-高级系统设置-远程-选中“允许远程连接到此计算机”-应用-确定。在局域网内&#xff0c;拥有固定IP的话&#xff0c;就很容易远程处理事情了。若经过此步骤还不能远程的话&#xff0c;则需要查看系统是否开启了远程服务。“我的电脑”--管理…

微软推出“ Group Transcribe”应用,多人多语言会议实时高准确度文字转录并翻译

近期&#xff0c;微软针对面对面对话和会议推出了免费实时语音到文字转录和翻译应用程序——Group Transcribe。一方面&#xff0c;Group Transcribe可以通过手机把会议的语音内容实时转录为文本&#xff0c;供与会者阅读和浏览。 另一方面&#xff0c;在实时交流过程中&#x…

STM32单片机外部中断配置讲解

2019独角兽企业重金招聘Python工程师标准>>> 单片机外部中断简介 所谓外部中断&#xff0c;就是通过外部信号所引起的中断&#xff0c;如单片机引脚上的电平变化(高电平、低电平)、边沿变化(上升沿、下降沿)等。51单片机有5个中断源&#xff0c;其中有两个是外部中断…

Android语音信号波形显示

简单地介绍了AudioRecord和AudioTrack的使用&#xff0c;这次就结合SurfaceView实现一个Android版的手机模拟信号示波器(PS&#xff1a;以前也讲过J2ME版的手机示波器)。最近物联网炒得很火&#xff0c;作为手机软件开发者&#xff0c;如何在不修改手机硬件电路的前提下实现与第…

科研费4年翻3倍,全球科研队伍突破8000人,滴滴致力打造出行领域核心技术

日前&#xff0c;十三届全国人大四次会议表决通过了《国民经济和社会发展第十四个五年规划和2035年远景目标纲要》&#xff08;下称《规划》&#xff09;。《规划》强调要坚持创新在我国现代化建设全局中的核心地位&#xff0c;把科技自立自强作为国家发展的战略支撑。 《规划…

c++ 继承访问控制初步

访问控制方式这里有篇很好的文章,其实内容也是总结cprimer上的内容 现在就按照这篇的文章举例进行学习. 思路 不同继承方式的影响主要体现在&#xff1a; 1、派生类成员对基类成员的访问控制。 2、派生类对象对基类成员的访问控制 三种继承方式 公有继承(public) 所有public和p…

Excel在.Net 环境下Web方式下驻留内存问题的解决

这段时间在VS 2003 的WebForm 方式下对Excel 进行操作&#xff0c;遇到一个最为头疼的问题就是对Excel操作完毕后Excel不能够正常关闭&#xff0c;系统退出后&#xff0c;Excel总是驻留在内存中。但是这段代码放到WinForm的程序中又没有问题。在网上进行了查找也没有找到有效可…

2.8 FSM之Moore和Mealy part3

来看看我们的Mealy机的设计吧~~。Mealy机的想法起源于&#xff1a;这里我们有输入&#xff0c;并且根据相应的输入我们的字符识别机能做出相应的应答也就是输出。所以我们为何不把输入和输出同时表达出来呢&#xff1f;这样我们就能把输出和抽象的状态分离出来。好处第一就是我…

​对标GPT-3、AlphaFold,智源研究院发布超大规模智能模型系统“悟道1.0”

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;3月20日&#xff0c;北京智源人工智能研究院发布我国首个超大规模智能模型系统“悟道1.0”。“悟道1.0”由智源研究院学术副院长、清华大学唐杰教授领衔&#xff0c;带领来自北京大学、清华大学、中国人民大学、中国科…

TCP Cluster for mqtt 技术实施方案

最前沿的网络技术&#xff0c;为你的网站带来国际化的用户体验和易用性&#xff0c;这一切只有Witmart.com能做到。

两台SQL Server数据同步解决方案

复制的概念复制是将一组数据从一个数据源拷贝到多个数据源的技术&#xff0c;是将一份数据发布到多个存储站点上的有效方式。使用复制技术&#xff0c;用户可以将一份数据发布到多台服务器上&#xff0c;从而使不同的服务器用户都可以在权限的许可的范围内共享这份数据。复制技…

一个用微软官方的OpenXml读写Excel 目前网上不太普及的方法。

新版本的xlsx是使用新的存储格式&#xff0c;貌似是处理过的XML。 传统的excel处理方法&#xff0c;我真的感觉像屎。用Oldeb不方便&#xff0c;用com组件要实际调用excel打开关闭&#xff0c;很容易出现死。 对于OpenXML我网上搜了一下&#xff0c;很多人没有介绍。所以我就这…

分析6千万条GitHub帖子,发现你的工作状态与表情符号强相关

作者 | 凌霄出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;新冠疫情使得远程办公的人数大幅度增加&#xff0c;然而&#xff0c;当越来越多的人远程工作时&#xff0c;人们的情绪和心理健康状态也难以通过日常面对面的交流来观察&#xff0c;雇主们也就无法获得员工…

软件定义网络 对我们有多重要?

软件定义网络(简称SDN)属于网络流量控制的下一个步骤。Tech Pro Research发布的调查报告正是以此为中心&#xff0c;旨在为我们展示企业如何使用SDN方案。 过去几年以来&#xff0c;以更为高效方式管理环境的需求正快速普及&#xff0c;这也使得网络领域的更高灵活性与控制手段…

SQL Server数据库六种数据移动方法

1. 通过工具DTS的设计器进行导入或导出DTS的设计器功能强大&#xff0c;支持多任务&#xff0c;也是可视化界面&#xff0c;容易操作&#xff0c;但知道的人一般不多&#xff0c;如果只是进行SQL Server数据库中部分表的移动&#xff0c;用这种方法最好&#xff0c;当然&#x…

[企业化NET]Window Server 2008 R2[3]-SVN 服务端 和 客户端 基本使用

1. 服务器基本安装即问题解决记录 √ 2. SVN环境搭建和客户端使用 2.1 服务端 和 客户端 安装 √ 2.2 项目建立与基本使用 √ 2.3 基本冲突解决,并版&#xff0c;tags 3. 数据库安装 4. 邮件服务器搭建 5. JIRA环境搭建和使用 6. CC.NET项目持续发布工具…

又一个Jupyter神器,操作Excel自动生成Python代码

来源 | Python数据科学&#xff08;ID: PyDataScience&#xff09;不得不说&#xff0c;Jupyter对于表的处理真的是越来越方便了&#xff0c;很多库可以直接实现可视化操作&#xff0c;无需写代码。但是这还不够&#xff0c;最近看到一个神器叫Mito&#xff0c;它真的是做到了无…

CIR:2020年全球数据中心应用AOC市场达$42亿

未来十年&#xff0c;QSFP和CXP将占有源光缆销售收入的大部分。到2020年&#xff0c;QSFP和QSFP28销售收入将分别达到7.27亿美元和7.41亿美元。 根据CIR(CommunicationsIndustryResearchers)的最新报告(《2015有源光缆市场&#xff1a;数据中心和高性能计算市场》)&#xff0c;…

Visual C#创建资源文件

资源文件顾名思义就是存放资源的文件。资源文件在程序设计中有着自身独特的优势&#xff0c;他独立于源程序&#xff0c;这样资源文件就可以被多个程序使用。同时在程序设计的时候&#xff0c;有时出于安全或者其他方面因素的考虑&#xff0c;把重要东西存放在资源文件中&#…

给IIS添加CA证书以支持https

一、在IIS中生成Certificate Signing Request (CSR) 个人理解&#xff1a;生成CSR就是生成“私钥/公钥对”之后从中提取出公钥。 1. 打开IIS Manager&#xff0c;在根节点中选择Server Certificates&#xff08;服务器证书&#xff09;&#xff0c;点击右侧的Create Certificat…

MathWorks的AI之路:面向工业场景,打通开发到部署的全链路

作者 | 阿司匹林 AI正在快速发展&#xff0c;并在更多的领域落地。对于MATLAB和Simulink的开发商MathWorks来说&#xff0c;把握AI的机会&#xff0c;显得尤为重要。 不少人对MATLAB等的印象依然停留在学校期间学习的高级线性代数解题器的阶段。然而&#xff0c;MATLAB在几年前…

《Android应用开发攻略》——1.3 从命令行创建 “Hello, World”应用程序

1.3 从命令行创建 “Hello, World”应用程序 Ian Darwin1.3.1 问题你想在不使用Eclipse ADT插件的情况下创建新的Android项目。1.3.2 解决方案使用Android开发工具包&#xff08;Android Development Kit&#xff0c;ADK&#xff09;中的android工具&#xff0c;利用creat proj…

将Excel文件数据库导入SQL Server

将Excel文件数据库导入SQL Server的三种方案//方案一&#xff1a; 通过OleDB方式获取Excel文件的数据&#xff0c;然后通过DataSet中转到SQL Server openFileDialog new OpenFileDialog();openFileDialog.Filter "Excel files(*.xls)|*.xls"; if(openFileDialog.…

Android----PopupWindow

Android的对话框有两种&#xff1a;PopupWindow和AlertDialog。它们的不同点在于&#xff1a;  AlertDialog的位置固定&#xff0c;而PopupWindow的位置可以随意  AlertDialog是非阻塞线程的&#xff0c;而PopupWindow是阻塞线程的 PopupWindow的位置按照有无偏移分&#x…

GitLab 在中国成立公司极狐,GitHub 还会远吗?

作者 | 宋慧 责编 | 苏宓出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;开源的种子已在中国落地开花。今天&#xff0c;中国的开源圈再次迎来一大盛事&#xff1a;全球第二大开源代码托管和项目管理平台 GitLab与红杉宽带等基金正式宣布成立中国合资公司极狐信…