【愚公系列】2023年10月 Winform控件专题 2023秋招Winform高频面试题

在这里插入图片描述

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

文章目录


🚀Winform常见笔面试题

🔎1. 如何设置窗体页面的默认提交按钮?

设置Form的AcceptButton属性,将用户按Enter时,就相当于单击了AcceptButton属性指定的按钮,就会引发它的Click事件。

🔎2. 怎么让一个窗体在运行时,只能打开一个?

1)可以通过遍历Application的OpenedForms集合,从中如果找到了该Form,将其激活即可

2)给该Form定义静态创建方法,除非该页面已经关闭或释放,否则直接返回该实例,不重复创建

public static Form1 frm;

//静态构造方法

public static Form1 CreateInstance()
{if (frm== null || frm.IsDisposed)
	  {
​          frm= new Form1();
	  }return frm;
}

🔎3. Form中有多个按钮,如何做到让它们都响应同一个单击事件处理程序,显示它们各自的名称信息?

先定义一个实现该效果的事件处理程序:

private void Btn_Click(object sender,EventArgs e)
{Button btn=(Button)sender;

​    MessageBox.Show($”点击的按钮是:{btn.Text});

}

然后订阅按钮的单击事件,

如Btn1按钮的订阅:Btn1.Click+=Btn_Click;

Btn2按钮的订阅:Btn2.Click+=Btn_Click;

Btnn按钮的订阅:Btnn.Click+=Btn_Click;

🔎4. 如何让Form的尺寸在运行时不可调整?

1)首先将Form的FormBoderStyle属性设置为:FixedSingle/Fixed3D/FixedDialog/FixedToolWindow;

2)再将Form的MaximizeBox设置为False

然后,运行时,Form的大小就不可调整了。

🔎5. 将Form2作为子窗体显示在Form1内,如何实现?

1)将Form1的IsMdiContainer属性设置为True;

2)Form2 f2=new Form2();

f2.MdiParent=this;(这里的this指Form1,假设当前页就是Form1)

F2.Show();

🔎6. Winform中,Form之间传值方式有哪些?

(1)通过Tag属性

(2)通过构造函数(在要接收值的Form页代码后台,定义一个带参数的构造函数)

(3)在接收值的Form代码后台文件中,定义一个public的变量

(4)通过事件参数传值

🔎7. Winform中,怎么实现Form2中点击打开按钮,打开Form1,输入文本,再点击Form1中的“确定”按钮,把输入的值显示到Form2的文本框中?

首先自定义一个事件参数TextBoxArgs:

public class TextBoxArgs:EventArgs
{public string TxtValue{get;set}public TextBoxArgs(string val){

​      TextValue=val;
	}
}

在Form1后台声明一个事件:public event Action<object,TextBoxArgs> SetTextBoxValue;

Form2中:

在Form2的”打开”按钮的Click事件中:

Form1 f1=new Form1();

f1.SetTextBoxValue+=F1_SetTextBoxValue;

f1.Show();

private void F1_SetTextBoxValue(object sender,TextBoxArgs e)
{
	txtValue.Text=e.TxtValue;
}

Form1中:

Form1的确定按钮的Click事件处理程序中:

string txtValue=txtInfo.Text.Trim();

TextBoxArgs arg=new TextBoxArgs(txtValue);

SetTextBoxValue?.Invoke(this,arg);

完成!

🔎8. 在Winform应用程序中,Appplication.Exit Form.Close有什么不同?

** Appplication.Exit()表示退出应用程序,Form.Close()表示关闭当前Form。

一般只有当Form是启动窗体时,它们才会有一样的效果,如果是非启动窗体,Form.Close()只是关闭当前Form而已。

🔎9. 在Winform中,我们发现在一个Form相关的cs文件有两个,它们的类名都是一样的,只是代码后台类文件中的class之前有partical修饰而已,这是为什么?

C# 2.0可以将类、结构、接口的定义拆分到两个或多个源文件中,用partial关键字修饰。这里也是这个道理。

Form分为两个类文件,其实还是只一个类,一个文件名是xx.Designer.cs 表示Form的UI代码文件,其中的代码是自动生成的,一般不建议去修改;另一个以.cs结尾的是后台文件文件,我们可在其中自己代码。等到编译运行时,系统会自动将两部分合成一个类。

🔎10. 如何在关闭窗体时,可以取消关闭?

在窗体的Form_Closing事件中,首先显示询问消息框,当用户点击“是”才执行关闭,当点击“否”,则取消关闭,实现方式如下:

private void Form1_Closing(object sender,FormClosingEventArgs e)
{

	if(MessageBox.Show(“您确定要关闭该页吗?”,”关闭提示”, MessageBoxButtons.YesNo, MessageBoxIcon.Question)==DialogResult.No)
	{
		e.Cancel=true;
	}
}

🔎11. DataGridView中添加了一个ComboBox列,如何使用?

如果DataGridView是要绑定数据的话,首先设置这个列的DataPropertyName,如果该列对应的数据源中的列是编号的话,就设置该编号列的列名或属性名;

然后在页面的Load事件中,在绑定DataGridView的数据源之前,先获取该列,指定该下拉框列的DataSource.

绑定下拉框列的数据源:

DataGridViewComboBoxColumn colCbo = dgvList.Columns["colCboName"] as DataGridViewComboBoxColumn;

colCbo .DataSource = GetCboList();

colCbo .DisplayMember = "ClassName";

colCbo .ValueMember = "ClassId";

再指定DataGridView的数据源:

DgvList.DataSource=list;

🔎12. 在Form中,实现无边框窗体拖动功能?

首先:将Form的FormBorderStyle设置为None.

然后,在工具箱中拖一个Panel控件到Form中,并将Panel控件的Dock设置为:Top.

这时的Form因为没有边框,是不能拖动的,接下来,我们来实现拖动效果:

先注册Panel的MouseDown和MouseMove事件,

Point point = new Point();bool isMove = false;//是否移动private void pTop_MouseDown(object sender, MouseEventArgs e){

​      point = e.Location;//按住的点

​      isMove = true;}private void pTop_MouseMove(object sender, MouseEventArgs e){Point pointNew;if (e.Button == MouseButtons.Left && isMove){

​        pointNew = e.Location;//按住的点拖动到的位置Point fPointNew = new Point(pointNew.X - point.X, pointNew.Y - point.Y);//相对于原来起点的距离点的描述this.Location += new Size(fPointNew);}

🔎13. 实现一个能动态添加多层次结构的TreeView节点的递归方法(以菜单数据为例)

private void AddTreeNodes(List<MenuInfo> mList, TreeNode pNode, int pId){var subList = mList.Where(m => m.ParentId == pId);foreach(var child in subList){TreeNode node= new TreeNode ();

​                node.Name = child.MenuId.ToString();

​                node.Text = child.MenuName;//添加到谁下边if (pNode!= null)

​                    pNode.Nodes.Add(node);else

​                    tvList.Nodes.Add(node);AddTreeNodes(mList, node, child.MenuId);}}

​ 调用时:AddTreeNodes(allMenus,null,0);即可

🔎14. Form中的控件与数据可以实现双向绑定吗?

使用DataBing可以实现自动绑定,为Form定义一个实体模型,将控件的属性与实体模型中的属性绑定在一起,当页面控件的属性值改变时,模型中的属性值自动更新,不需要一一再去获取;当模型中的属性值修改时,控件的属性值也会自动更新。

模型基类,实现INotifyPropertyChanged接口,可以通知客户端属性性已更改

   public class ViewModelBase : INotifyPropertyChanged
​    {public event PropertyChangedEventHandler PropertyChanged;public void OnPropertyChanged([CallerMemberName] string propertyName=""){

​            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}} 

页面的模型:

Public class UserInfo:ViewModelBase 

{string userName;public string UserName

​    {get{return  userName; }set{

​        userName= value;OnPropertyChanged();}}

 int age;public int Age

​    {get{return  age; }set{

​        age= value;OnPropertyChanged();}}

}

Form页面 控件绑定:

Form1_Load事件处理程序:

 UserInfo userInfo=null;

 private void Form1_Load(object sender, EventArgs e)

 {

​      userInfo=new UserInfo ();

​      txtUserName.DataBindings.Add("Text", userInfo, "UserName");

​      txtUserAge.DataBindings.Add("Text", userInfo, "Age");

 }     

🔎15. ComboBox控件绑定枚举类型如何实现?

比如定义一个星期的枚举类型

public enum Weekdays{

​     星期一,星期二,星期三,星期四,星期五,星期六,星期日

​    }//定义WeekDayInfo实体类public class WeekDayInfo

{

public int DayValue{get;set;}

public string DayName{get;set;}

}//将枚举类型中的值转换成List<WeekDayInfo>public List<WeekDayInfo>  GetWeekDayList()

{	

List<WeekDayInfo> list=new List<WeekDayInfo>();

foreach(int wdVal in Enum.GetValues(typeof(Weekdays)))

{WeekDayInfo wd=new WeekDayInfo();

​    wd.DayValue=wdVal;

​    wd.DayName=Enum.GetName(typeof(Weekdays),wdVal);

​    list.Add(wd);

}	

return list;

}

然后在Form1的Load事件中绑定数据源:

comboBox1.DisplayMember = "DayName";

comboBox1.ValueMember = "DayValue";

comboBox1.DataSource = GetWeekDayList();

🔎16. Form窗体的常用事件有哪些?

Form的常用事件主要是:Load(加载窗体时发生)、FormClosing(正在关闭时还示关闭)、Activated(窗体被激活时)、SizeChanged(Size属性更改时)、Resize(调整窗体大小时)、LocationChanged(Location属性更改时)

🔎17. Windows.Forms.Timer 计时器如何实现动态时间

这个计时器是基于UI的,可以修改控件的。首先,直接在Form上拖控件Timer,设置Enabled=true(程序运行计时器立即运行);然后设置时间间隔:Interval 1000(ms),表示每隔1s执行一次。

最后,写每隔Interval设置的时间间隔执行的Tick事件即可。

private void timer1_Tick(object sender, EventArgs e)   
{      

  this.label1.Text = DateTime.Now.ToString(“yyyy-MM-dd HH:mm:ss”);   

}

🔎18. Winform中,控件开发分为哪些?

在Winform中,自定义控件可分为三种:

1)复合控件:将现有标准控件组合起来成一个新控件

如public class UserCardControl:UserControl{ }

2)扩展控件:继承于现有控件,扩展新的特性或重绘外观

如:public class ButtonEx:Button { }

3)自定义控件:完全地自定义一个控件。该控件继承于Control,重写OnPaint()实现控件外观绘制。

Public class NewControl:Control

{ }

🔎19. 如何在Form加载时,动态添加控件到Form中?

这里以Label为例说明。

在Form1的加载加载中:

private void Form1_Load(object sender, EventArgs e)
{

	Label label1=new Label()
	{
	
	  Text=“欢迎来到这里!!!”,
	
	  ForeColor = System.Drawing.Color.Red,
	
	 Name=”label1”,
	
	 AutoSize=true,
	
	 Location=new System.Drawing.Point(48, 37);
	
	};
	 this.Controls.Add(label1);
}

这样就将一个Label控件添加到了Form中。

🔎20. 怎样将一个Form显示在Panel之中?

​ 将Form1作为父窗体,在窗体上放一个Panel控件,将Form2显示在Panel之中。

​ 首先,要将Form2的TopLevel设置为false,因为顶级窗体不能显示在其他控件之中。

​ 其次,将Form2的FormBorderStyle设置为:FormBorderSyle.None。无边框。

​ Form2添加到Panel的代码如下:

panelPage.Controls.Clear();//移除所有控件

Form2 frm2 = new Form2 ();
frm2 .TopLevel = false;
frm2 .FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
panelPage.Controls.Add(frm2 )

frm2 .Show();

🔎21. Winform布局时,如何实现让Form中的GroupBox的宽度随Form的尺寸调整而自动变化,高度不变?

如果GroupBox与Form的左、上、右是没有间距的,可以直接设置GroupBox控件的Dock属性为:top 即可;如果GroupBox与Form的左、上、右是有一定间距的,那Dock属性就无法做到了,这时就要考虑Anchor属性了,设置GroupBox的Anchor属性为:Left,Top,Right, 然后再调整好控件与Form左、上、右的间距就OK了。

🔎22. Winform中如何跨线程修改控件的值?

因为Winform应用程序是单线程的。对于某一个控件来说,只有创建该控件的线程才能修改它的值。对Winform来说,在窗体中拖一个控件,它由程序的主线程创建。因而,如果我们又另开一个线程,那么如果我们想要在这个线程中直接去修改该控件的值,就会报错。

那么如果,我们仍然想要改控件的值,该如何做呢?

我们可以通过,在这个子线程中,通过this.Invoke() 或 this.BeginInvoke()的方式通过执行委托的方式,在委托里去修改,就可以。

代码如下:

This.Invoke(new Action(()=>{

	 Label1.Text=”您好!”;

}));

🔎23. 如何设置MenuStrip控件中菜单项的快捷键?

菜单项的快捷键有两种设置方式:

(1) Alt快捷键 菜单项Text属性设置的文本加上(&+键码)就可以

(2) Ctrl或Shift快捷键,设置菜单项的ShortcutKeys属性就可以了。

🔎24. 怎么设置StatusStrip控件中项之间的分隔线?

StatusStrip控件中没有分隔线的项,那么 如果各项之间要显示分隔线,怎么办呢?答案很简单。

在StatusStrip中添加一个StatusLabel子项,将它的BorderSides改成Left或Right即可。

🔎25. 如何根据提供的值列表,设置CheckedListBox中项的勾选状态?

假设提供的值列表是List valueList

public static void SetCheck(CheckedListBox cblItems, List<string> valueList)
{
  foreach (string str in valueList)
  {
	   for (int i = 0; i < cblItems.Items.Count; i++)
	   {
		    if (cblItems.GetItemText(cblItems.Items[i]) == str)
		    {
		     	cblItems.SetItemChecked(i, true);
		    }
	  }
 }
}

🔎26. 如何将Dictionary<int,string>中存储的信息绑定到ListBox中?

因为ListBox的数据源可以是DataTable或List,但Dictionary却不能直接作为它的数据源。但我们可以利用BindingSource来作为连接数据源与控件的桥梁。

实现如下:

Dictionary<int,string> userList=new Dictionary<int,string>();

userList.Add(101,”李明”);

userList.Add(102,”刘红”);

userList.Add(103,”张三”);

//绑定数据

comboBox1.DataSource = new BindingSource(dict, null);

comboBox1.ValueMember = "Key";//文本对应的值

comboBox1.DisplayMember = "Value";//显示的文本

🔎27. DevExpress Winform 常用控件有哪些?

\1. SimpleButton(普通按钮) 2. ButtonEdit(编辑按钮) 3. CheckEdit(复选/单选框)

\4. TextEdit(文本框) 5. SpinEdit(数值选择控件) 6. DateEdit(日期控件)

\7. TimeEdit(时间控件) 8. ComboBoxEdit(下拉框) 9. LookUpEdit(下拉列表视图)

\10. LayoutControl(排版控件) 11. SplitContainerControl(分割容器控件) 12. BarManager(菜单控件)

\13. XtraScrollableControl控件 14. TreeList(树状列表控件) 15. XtraTabControl(Tab 页控件)

\16. MarqueeProgressBarControl(进度条控件) 17. DXValidationProvider(验证控件)

🔎28. DevExpress Winform 如何实现单选按钮?

在DevExpress中已经看不到RadioButton控件,只有RadioGroup,但它却不是我们想要的单选按钮。

其实这里我们仍然使用CheckEdit控件来实现,示例如下:

CheckEdit.Properties.CheckStyle = DevExpress.XtraEditors.Controls.CheckStyles.Radio;

此外,必须确保所设定的所有单选按钮设置RadioGroupIndex相同的索引编号。

🔎29. 在DevExpress中,如何修改SimpleButton的背景色?

要对simplebutton按钮控件设置背景色,除了给其Appearance下的BackColor属性赋值之外,还需要将ButtonStyle的值,设置为除Default和Office2003之外的其它值,背景色才会起效,否则没有任何改变。比如将ButtonStyle为Flat。

🔎30. 在DevExpress中,怎样让TextEdit只能输入6位数字?

首先,将TextEdit的 MaskType设置为:Numeric,

然后,将Edit Mask改为:“######”即可。

度条控件) 17. DXValidationProvider(验证控件)


🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

  • 4
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 作为一名程序员,我在2023对自己的计划包括: 1. 不断学习和提升技能:我会继续学习新的编程语言和框架,以及不断提高编码能力。 2. 参加行业相关的培训和会议:我会参加各种行业相关的培训课程和会议,以便获得最新的行业知识和技能。 3. 参加项目并积累经验:我会参加各种项目,以便积累丰富的经验,并提升个人能力。 4. 在业内建立良好的人脉关系:我会努力与业内的同行建立良好的人脉关系,并与他们保持联系。 5. 寻找更好的发展机会:我会不断寻找更好的发展机会,以便在职业生涯中取得更大的成功。 总之,我在2023会努力工作,不断学习和提升,并寻找更好的发展机会,以在职业生涯中取得更大的成功。 ### 回答2: 2023的计划对于我作为一名程序员来说十分重要,我希望能够提升自己的技能水平并取得更好的职业发展。以下是我的计划: 首先,我计划继续学习并掌握新的编程语言和技术。随着科技的不断发展,编程语言和技术也在不断更新换代,作为一名程序员,保持学习的状态是必不可少的。我将花费更多的时间学习目前主流的编程语言,如Python、Java等,并尝试掌握最新的前端和后端技术。通过不断学习,我希望能够拥有更广泛的技术视野和更强大的技术能力。 其次,我计划参与更多的项目和实践。在理论学习之外,实践是提升技能的关键。我计划积极寻找项目机会,无论是个人项目还是团队项目,都可以提供宝贵的实践机会。通过参与各种项目,我可以锻炼解决问题的能力,提高编码和协作能力。同时,我也希望通过实践中的挑战和失败,不断完善自己,进一步提高自己的技术水平和经验。 第三,我计划参加相关的培训和技术交流活动。参加培训和技术交流活动可以与其他程序员交流和学习,了解行业最新动态和趋势。我计划参加各种技术研讨会、讲座和培训班,通过与行业专家和其他程序员的交流,深入了解各种编程技术和最佳实践。同时,我也希望能够积极参与技术社区,与其他程序员分享自己的经验和见解,不断提高自己的影响力和口碑。 最后,我计划在个人项目和开源社区上做出更多的贡献。通过自己的努力,我希望能够在个人项目中实现一些有意义的功能或解决一些实际问题,并将其开源。通过开源社区的贡献,我可以帮助他人解决问题,同时也能够借助其他人的反馈和指导,不断改进自己的代码和设计能力。 总之,2023对于我作为一名程序员来说是充满挑战和机遇的一。我将不懈努力,持续学习和实践,不断提升自己的技能水平和职业发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚公搬代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值