@[TOC](文章目录)
参考文章: WPF基础笔记 WPF(1)WPF工程创建 WPF(2)WPF之Image组件 WPF(3)WPF之Button组件 WPF(5)WPF之DataGrid控件 WPF(6)WPF之TextBox控件 WPF(7)WPF之ProgressBar控件 WPF(8)WPF之GroupBox控件(登录界面示例) WPF(9)WPF之常用弹窗的工具类 WPF(10)WPF之OpenFileDialog WPF(11)WPF之DataGrid的CellTemplateSelector使用
委托delegate
有时间可以看一下这个大佬写的文章, 写得挺好的: http://www.tracefact.net/tech/
参考文章①: C# 委托(delegate)和事件(event)详解 对应出处: C#中的委托和事件 - Part.1
委托: 可以理解为函数指针
图一:图二:
as关键字
参考文章: C#中as用法
在程序中,进行类型转换是常见的事,C#支持基本的强制类型转换方法,例如
Object obj1 = new NewType();
NewType newValue = (NewType)obj1;
这样强制转换的时候,这个过程是不安全的,因此需要用try-catch语句进行保护
但是上面的写法在C#中已是过时的写法,也是比较低效的写法,比较高效且时尚的写法是用as操作符,如下:
Object obj1 = new NewType();
NewTypenewValue = obj1 as NewType;
在C#中提供的很好的类型转换方式总结为:
- Object => 已知引用类型——使用as操作符完成;
- Object => 已知值类型——先使用is操作符来进行判断,再用类型强转换方式进行转换;
- 已知引用类型之间转换——首先需要相应类型提供转换函数,再用类型强转换方式进行转换;
- 已知值类型之间转换——最好使用系统提供的Conver类所涉及的静态方法。
C#类型判断 sizeof typeof GetType() is
参考文章: https://blog.csdn.net/weixin_38566632/article/details/117702378
sizeof
运算符可以获知数据类型在内存中占用几个字节;typeof
运算符可以获取数据类型的 CTS 类型名;GetType()
方法可以获得变量的数据类型;is
运算符检验某个对象是否为某种类型,用法更为简洁;
Console.WriteLine("double: " + sizeof(double)); // 8 (字节)
Console.WriteLine("double: " + typeof(double)); // System.Double
double f = 3.14;
Console.WriteLine("f: " + f.GetType()); // System.Double
Cat kitty = new Cat();
Console.WriteLine("kitty: " + kitty.GetType()); // TypeJudge.Cat
//判断kitty是不是猫有以下两种方法,第二种方法更简洁
if(kitty.GetType() == typeof(Cat))
Console.WriteLine("Kitty is a cat."); // 会输出
if(kitty is Cat)
Console.WriteLine("Kitty is a cat."); // 会输出
//Kitty既然是猫,那它当然也是哺乳动物了 (类Cat继承自Mammal)
if (kitty is Mammal)
Console.WriteLine("Kitty is a Mammal."); // 会输出
virtual关键字
参考文章: C# 虚方法virtual详解: 这篇文章的例子写的很好
readonly关键字
参考文章: const与readonly知多少
- const修饰的常量在声明的时候必须初始化; readonly修饰的常量则可以延迟到构造函数初始化
- const修饰的常量在编译期间就被解析,即常量值被替换成初始化的值; readonly修饰的常量则延迟到运行的时候
- cosnt的静态常量只能被声明为简单的数据类型(int以及浮点型)、枚举、布尔或者字符串型,而readonly动态常量则除了这些类型,还可以修饰一些对象类型,如DateTime类型
通常用在类中属性前面 使用了readonly的属性,只能在定义时,或者构造函数中初始化,其他的地方都不能再修改其值
class Age
{
//年纪添加了 readonly修饰符
//1.可以在定义时对其赋值
readonly int year = 20;
//2.在构造函数中赋值
Age(int year)
{
this.year = year;
}
//3.但是不能在其他地方赋值
void ChangeYear()
{
year = 1967; // 如果这里赋值了,会出现编译错误
}
}
WPF中MessageBox消息框的用法
注意: 在WPF中, 有两个MessageBox, 一个
System.Windows.MessageBox.Show("123");
另一个是System.Windows.Forms.MessageBox.Show("123");
接下来都是介绍第一个Windows.MessageBox的show方法另外: show()方法显示的都是模态对话框
- 模态对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。
- 非模态对话框,它弹出后,本程序其他窗口仍能响应用户输入
MessageBox.Show("This MessageBox has extra options.\n\nHello, world?", "My App", MessageBoxButton.YesNoCancel);
MessageBox.Show("哈哈哈哈", "标题", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
参考文章①: Wpf--->自定义MessageBox,MessageBox默认的几种样式,MessageBox.Show()的枚举参数: 这篇文章介绍了MessageBox.show()函数的各个参数及用法
参考文章②: WPF入门教程MessageBox: 这篇文章还补充写了MessageBox.Show()函数的返回值, 这样我们可以知道用户点击了那个按钮, 示例如下:
MessageBoxResult result = MessageBox.Show("Would you like to greet the world with a \"Hello, world\"?", "My App", MessageBoxButton.YesNoCancel);
switch(result)
{
case MessageBoxResult.Yes:
MessageBox.Show("Hello to you too!", "My App");
break;
case MessageBoxResult.No:
MessageBox.Show("Oh well, too bad!", "My App");
break;
case MessageBoxResult.Cancel:
MessageBox.Show("Nevermind then...", "My App");
break;
}
internal关键字
参考文章: C# 访问修饰符 public、private、protectrd、internal、protected internal 访问权限权限级别: 大→小:
public > protected internal > internal > protected > private
访问修饰符 | 权限说明 |
private | 私有成员,在类的内部才可以访问,实例不能访问 |
protected | 保护成员,该类内部和子类中可以访问,实例不能访问 |
public | 公共成员,完全公开,没有访问限制 |
internal | 默认的类访问级别,当前项目(同一程序集)中可以访问: 在VS开发环境中,一个解决方案可以包含多个项目,而每个项目就是一个程序集 |
protected internal | 在同一程序集内和子类中可以访问 (protected权限 + internal权限) |
WPF中的Grid和DataGrid的用法
参考文章①: WPF(5)WPF之DataGrid控件, 这篇文章有近两万字, 详细地介绍了DataGrid的用法
参考文章②: 关于wpf中的grid和datagrid
- grid是布局控件(容器), 是用于在窗体(或页面)上布置其他控件的控件
- datagrid是数据表格, 是一个控件,用于显示从数据库中读取的表格数据
xaml中的Binding
参考文章: 《深入浅出WPF》学习笔记: 最前面的部分有Binding的介绍参考教程: WPF项目实战合集(2022终结版): 这个视频写的很清晰易懂为什么要用? 举个例子, 一个滚动条 slider 和一个文本框, 要将滚动条的长度显示到文本框中, 并且当文本框的内容发生改变时, 也会让滚动条的长度发生改变, 那我们就可以用双向绑定:
<StackPanel>
<Slider x:Name="slider" Margin="5"/>
<TextBox Text="{Binding ElementName=slider, Path=Value}" Margin="5" Height="30"/>
<TextBox Text="{Binding ElementName=slider, Path=Value}" Margin="5" Height="30"/>
<!-- ElementName表示和谁进行绑定, 用Path来设置文本框的内容为Slider的长度Value -->
</StackPanel>
在WPF中,Binding更注重于表达它是一种桥梁一样的关联关系。如果把Binding比作数据的桥梁,那么他的两端分别是Binding的源(Source)和目标(Target), 数据从哪里来哪里就是源,Binding是架在中间的桥梁,Binding目标就是数据要往哪里去(即把桥架向哪里)。因此,一般情况下,Binding源是逻辑层的对象,Binding目标是UI层的控件对象,这样,数据源就会源源不断地通过Binding送往UI层、被UI层展现,也就完成了数据驱动UI的过程。
控制Binding数据流向的属性是Mode,它的类型是BindingMode枚举,它的值有:
- OneTime 只绑定一次
- OneWay 单向绑定 (只有拖动滚动条的时候, 文本框的内容才发生改变) ==> 数据向target(ElementName=slider)进行发送
- OneWayToSource (只有当文本框的内容改变时, 滚动条才变) ==> 数据向source发送
- TwoWay 双向绑定
- Defalut
- 注意:Default的值是指Binding的模式会根据目标的实际情况来确定,比如若是可编辑的(如TextBox的Text属性),Defalut就会采用双向模式;若是只读的(如TextBox的Text属性)就会采用单向模式。
<StackPanel>
<Slider x:Name="slider" Margin="5"/>
<!-- 下面的写法中, 源头target都是slider, 目标都是TextBox❗ -->
<TextBox Text="{Binding ElementName=slider, Path=Value, Mode=OneTime}" Margin="5" Height="30"/>
<TextBox Text="{Binding ElementName=slider, Path=Value, Mode=OneWay}" Margin="5" Height="30"/>
<TextBox Text="{Binding ElementName=slider, Path=Value, Mode=OneWayToSource}" Margin="5" Height="30"/>
<TextBox Text="{Binding ElementName=slider, Path=Value, Mode=TwoWay}" Margin="5" Height="30"/>
</StackPanel>
类Student有属性Name
internal class Students
{
public string Name { get; set; }
}
将文本框的内容和类Student的属性Name绑定起来
<StackPanel>
<TextBox Text="{Binding Name}"
Margin="5"
Height="30"/>
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new Students()
{
Name = "张三"
};
}
}