wpf 导出Excel Wpf Button 样式 wpf简单进度条 List泛型集合对象排序 C#集合
wpf 导出Excel
1 private void Button_Click_1(object sender, RoutedEventArgs e) 2 { 3 4 ExportDataGridSaveAs(true, this.data); 5 } 6 #region wpf客户端 导出DataGrid数据到Excel 7 8 /// <summary> 9 /// CSV格式化 10 /// </summary> 11 /// <param name="data">数据</param> 12 /// <returns>格式化数据</returns> 13 private static string FormatCsvField(string data) 14 { 15 return String.Format("\"{0}\"", data.Replace("\"", "\"\"\"").Replace("\n", "").Replace("\r", "")); 16 } 17 18 19 20 /// <summary> 21 /// 导出DataGrid数据到Excel 22 /// </summary> 23 /// <param name="withHeaders">是否需要表头</param> 24 /// <param name="grid">DataGrid</param> 25 /// <param name="dataBind"></param> 26 /// <returns>Excel内容字符串</returns> 27 public static string ExportDataGrid(bool withHeaders, System.Windows.Controls.DataGrid grid, bool dataBind) 28 { 29 try 30 { 31 var strBuilder = new System.Text.StringBuilder(); 32 var source = (grid.ItemsSource as System.Collections.IList); 33 if (source == null) return ""; 34 var headers = new List<string>(); 35 List<string> bt = new List<string>(); 36 37 foreach (var hr in grid.Columns) 38 { 39 // DataGridTextColumn textcol = hr. as DataGridTextColumn; 40 headers.Add(hr.Header.ToString()); 41 if (hr is DataGridTextColumn)//列绑定数据 42 { 43 DataGridTextColumn textcol = hr as DataGridTextColumn; 44 if (textcol != null) 45 bt.Add((textcol.Binding as Binding).Path.Path.ToString()); //获取绑定源 46 47 } 48 else if (hr is DataGridTemplateColumn) 49 { 50 if (hr.Header.Equals("操作")) 51 bt.Add("Id"); 52 } 53 else 54 { 55 56 } 57 } 58 strBuilder.Append(String.Join(",", headers.ToArray())).Append("\r\n"); 59 foreach (var data in source) 60 { 61 var csvRow = new List<string>(); 62 foreach (var ab in bt) 63 { 64 string s = ReflectionUtil.GetProperty(data, ab).ToString(); 65 if (s != null) 66 { 67 csvRow.Add(FormatCsvField(s)); 68 } 69 else 70 { 71 csvRow.Add("\t"); 72 } 73 } 74 strBuilder.Append(String.Join(",", csvRow.ToArray())).Append("\r\n"); 75 // strBuilder.Append(String.Join(",", csvRow.ToArray())).Append("\t"); 76 } 77 return strBuilder.ToString(); 78 } 79 catch (Exception ex) 80 { 81 // LogHelper.Error(ex); 82 return ""; 83 } 84 } 85 public class ReflectionUtil 86 { 87 public static object GetProperty(object obj, string propertyName) 88 { 89 PropertyInfo info = obj.GetType().GetProperty(propertyName); 90 if (info == null && propertyName.Split('.').Count() > 0) 91 { 92 object o = ReflectionUtil.GetProperty(obj, propertyName.Split('.')[0]); 93 int index = propertyName.IndexOf('.'); 94 string end = propertyName.Substring(index + 1, propertyName.Length - index - 1); 95 return ReflectionUtil.GetProperty(o, end); 96 } 97 object result = null; 98 try 99 { 100 result = info.GetValue(obj, null); 101 } 102 catch (TargetException) 103 { 104 return ""; 105 } 106 return result == null ? "" : result; 107 } 108 } 109 /// <summary> 110 /// 导出DataGrid数据到Excel为CVS文件 111 /// 使用utf8编码 中文是乱码 改用Unicode编码 112 /// 113 /// </summary> 114 /// <param name="withHeaders">是否带列头</param> 115 /// <param name="grid">DataGrid</param> 116 public static void ExportDataGridSaveAs(bool withHeaders, System.Windows.Controls.DataGrid grid) 117 { 118 try 119 { 120 string data = ExportDataGrid(true, grid, true); 121 var sfd = new Microsoft.Win32.SaveFileDialog 122 { 123 DefaultExt = "csv", 124 Filter = "CSV Files (*.csv)|*.csv|All files (*.*)|*.*", 125 FilterIndex = 1 126 }; 127 if (sfd.ShowDialog() == true) 128 { 129 using (Stream stream = sfd.OpenFile()) 130 { 131 using (var writer = new StreamWriter(stream, System.Text.Encoding.Unicode)) 132 { 133 data = data.Replace(",", "\t"); 134 writer.Write(data); 135 writer.Close(); 136 } 137 stream.Close(); 138 } 139 } 140 MessageBox.Show("导出成功!"); 141 } 142 catch (Exception ex) 143 { 144 // LogHelper.Error(ex); 145 } 146 } 147 148 #endregion 导出DataGrid数据到Excel 149 150
找了好多都有问题,这个可以分享给到家
转自:https://www.cnblogs.com/kmust/p/4412228.html
Wpf Button 样式
上图片:
默认 鼠标悬浮 鼠标按下
<Window.Resources> <Style x:Key="ButtonFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#F3F3F3" Offset="0"/> <GradientStop Color="#EBEBEB" Offset="0.5"/> <GradientStop Color="#DDDDDD" Offset="0.5"/> <GradientStop Color="#CDCDCD" Offset="1"/> </LinearGradientBrush> <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/> <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border Name="border" BorderThickness="1" BorderBrush="{TemplateBinding Background}" Background="{TemplateBinding Background}" CornerRadius="20"> <Label Name="label" FontSize="15" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></Label> </Border> <!-- <Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Themes:ButtonChrome>--> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" TargetName="border" Value="Green"></Setter> <Setter Property="BorderBrush" TargetName="border" Value="Green"></Setter> <Setter TargetName="label" Property="FontSize" Value="16"></Setter> <Setter TargetName="label" Property="Foreground" Value="yellow"></Setter> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="border" Value="Yellow"></Setter> <Setter Property="BorderBrush" TargetName="border" Value="Yellow"></Setter> <Setter TargetName="label" Property="FontSize" Value="17"></Setter> <Setter TargetName="label" Property="Foreground" Value="Green"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="#ADADAD"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Button Width="100" Height="40" Content="点击" Background="Gray" Style="{DynamicResource ButtonStyle1}" Click="Button_Click"/> </Grid> </Window>
wpf简单进度条
UserControl x:Class="WpfApplication1.UserControl2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" > <Viewbox> <Grid> <Border Name="MaxCircle" CornerRadius="500" Width="100" Height="100" Background="White" Opacity="0.2"/> <ed:Arc Name="FillArea" ArcThickness="0.02" ArcThicknessUnit="Percent" StartAngle="0" EndAngle="0" Width="95" Height="95" Stretch="None" Opacity="0.8" Fill="#86E02D"/> <Label Name="ShowLabel" Width="60" Height="60" FontFamily="宋体" FontWeight="Bold" Content="01" FontSize="32" Foreground="Black" Opacity="0.8" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" /> </Grid> </Viewbox> </UserControl>
List泛型集合对象排序
本文的重点主要是解决:List<T>对象集合的排序功能。
一、List<T>.Sort 方法 ()
MSDN对这个无参Sort()方法的介绍:使用默认比较器对整个List<T>中的元素进行排序。
从官方文档的介绍,很难的看出详细的解析,而且还要完整的知识结构去分析,上面提到了一个关键词:比较器。大致看了下,比较器是一个委托。在这里不去透析它的完整脉络,本文只去讲解怎么去解决两个实际的问题:
- List集合元素升序排列
- List集合元素降序排列
1.1.对于数字类型的调用
调用结果:为升序,无法满足降序。
示例:
1.2.对于字符串类型的调用
调用结果:把值解析成拼音字母,按照首个英文字母顺序升序排列,如果首字母相同,比较第二个的首字母。
示例:
1.3.对于自定义对象的调用
调用结果:无法完成方法的执行,运行报错。
示例:
总结:很显然这个无参的Sort()方法很难满足我们实际开发中需求,对于面向对象编程我们,常常就是对集合中的对象进行排序。
二、自定义对象类型默认排序
对象本身不是一个具体的值,在排序逻辑上显然要选择对象的一个属性进行排序。
1.1手动设置无参Sotr()方法的默认排序逻辑
将List的指定类型的类实现IComparable泛型接口,示例:
1 class Student:IComparable<Student> 2 { 3 4 public string Id { get; set; } 5 public string Name { get; set; } 6 public int Age { get; set; } 7 8 public int CompareTo(Student other) 9 { 10 //return other.Age.CompareTo(this.Age); // 年龄降序 11 return this.Age.CompareTo(other.Age); // 年龄升序 12 } 13 }
排序逻辑:this在前面就意味着指定按照这个属性升序,如果写在后面就是降序。
调用:
List<Student> list_obj = new List<Student> { new Student { Age=23,Name="tom"}, new Student { Age=18,Name="jack"}, new Student {Age=28, Name="bob"}, }; list_obj.Sort(); for (int i = 0; i < list_obj.Count; i++) { string output_result = string.Format("{0},年龄:{1}",list_obj[i].Name,list_obj[i].Age); Console.WriteLine(output_result); }
在调用Sort()方法的时候,就自动调用了我们实现接口的CompareTo方法的逻辑代码。
结果如图:
总结:此方法的实现,虽然解决了可以按照对象属性进行升序和降序,但是在实现CompareTo的方法里,指定的属性是固定的。这样的话显然
不灵活,那么下面就介绍另一种方法,解决该问题。
二、自定义对象类型动态排序
默认排序,通过实现IComparable泛型接口来完成。并且在实现ComparaTo接口里指定排序的属性是固定的,写死的。如果功能上有多条件排序(按照年龄、学号等等),默认排序就无法满足。
1.1为每一个要排序的属性写一个对应的排序类,一个排序逻辑对应一个排序类,示例:
//按照Id升序 class StudentOrderBy_Id_asc:IComparer<Student> { public int Compare(Student x, Student y) { return x.Id.CompareTo(y.Id); } } //按照年龄降序 class StudentOrderBy_Age_desc:IComparer<Student> { public int Compare(Student x, Student y) { return y.Age.CompareTo(x.Age); } }
1.2.调用
List<Student> list_obj = new List<Student> { new Student { Id=9,Age=23,Name="tom"}, new Student { Id=3,Age=18,Name="jack"}, new Student {Id=10,Age=28, Name="bob"}, new Student {Id=2,Age=30, Name="ben"}, }; //---按照ID升序---- list_obj.Sort(new StudentOrderBy_Id_asc()); Console.WriteLine("---按照ID升序----"); for (int i = 0; i < list_obj.Count; i++) { string output_result = string.Format("{0},学号:{1}",list_obj[i].Name,list_obj[i].Id); Console.WriteLine(output_result); } //---END按照ID升序---- //---按照年龄降序---- list_obj.Sort(new StudentOrderBy_Age_desc()); Console.WriteLine("---按照年龄降序----"); for (int i = 0; i < list_obj.Count; i++) { string output_result = string.Format("{0},年龄:{1}", list_obj[i].Name, list_obj[i].Age); Console.WriteLine(output_result); } //---END按照年龄降序----
1.3.输出结果:
1.4编写逻辑:
- 确定好要排序的属性和排序规则,为此写一个排序类。
- 编写Compare方法的排序逻辑(指定排序属性,排序逻辑)。
- 创建排序类的对象,作为参数参入,调用Sort()方法。
总结:本文主要是解决实际问题,要深入到细节原理,会涉及到一些知识点:冒泡排序、多态、比较器、委托。
在具备知识点的前提结合Msdn文档可以尝试透析原理。
C#集合
一、 集合概述
没有掌握集合的知识之前,我们通常都是用数组来存储元素。数组有一个很明显的特点就是,长度是固定的。假设,用数组存储一组员工信息,显然公司的员工数量是有流动性的,如果来了新员工,那么以现有的知识来思考,这个数组只能重新定义。能否建立一个动态的 “数组”,使我们可以对其进行动态的操作呢?下面就引入集合,来解决这个问题。
二、ArrayList
ArrayList属于非泛型集合,现在大多数情况用的很少了。文章里会首先介绍非泛型集合,是因为引出泛型集合,就像通过数组引出集合的概念一样。
ArrayList可能会介绍的详细一点,这都是为了后面的内容做铺垫。
1.简介
ArrayList非常类似于数组,可以填补数组的不足,进行元素的动态维护。数组的长度是固定的,而ArrayList的容量可以根据需要自动扩充,它的索引会根据程序的扩展而重新分配和调整。
ArrayList是可以动态维护的,因此在定义的时候可以指定容量,也可以不指定容量。
如图:
2.给ArrayList添加数据
a.通过Add()方法添加元素
Add()方法是将元素添加到集合结尾处,返回一个int类型,用于返回所添加元素的索引。
重点:如果Add()添加的元素是值类型,这些元素都会装箱处理转换为Object引用类型。因此ArrayList中所有的元素都是引用类型。
b.通过集合初始化器构造集合
3.存取ArrayList中的单个元素
ArrayList获取一个元素的方法和数组是一样的,也是通过索引来访问。需要注意的是,由于元素添加时都会被转换为object类型,所以在访问元素的时候必须把他们转换成原来的数据类型。
4.删除ArrayList中的元素
4.1.RemoveAt()根据索引删除指定元素。
使用索引删除元素还是存在一定的风险:
运行后,发现系统异常,因为ArrayList的索引会自动分配和调整,在上图注意事项1的集合中添加了三个元素,删除第一个元素后,索引为“2”的第三个元素就不存在了,长度动态的发生了变化,所以再删除索引为“2”的元素就会发生错误。如果存在索引为“2”的元素,那么删除之前和删除之后是两个不同的对象,这时候会导致数据不对。因此使用索引删除元素还是存在一定的风险的。
4.2.Remove()指定对象删除。
4.3.Clear()删除集合所有元素。
三、Hashtable
对于ArrayList集合我们通常会使用索引访问操作元素,但是这样的话就存在一个问题,使用这种方式必须知道要操作的索引是多少。
Hashtable可以针对这种情况解决问题,它为每个元素都取了一个有意义并且唯一的关键字,然后通过关键字来访问元素。
Hashtable,通常称为哈希表,也有人称它为“字典”。使用字典这个名词,是因为其数成非常类似于现实生活中的字典。Hashtable的数据是通过(key)键和值(value)来组织的。
如图:
1.添加元素:
Add(key,value)
2.获取Hashtable元素
2.1.和ArrayList不同,访问Hashtable元素时只能使用通过键名来获取具值。
如图:
用索引访问,程序运行时会提示“未将对象引用设置到对象的示例”。
2.2.由于添加时值被隐试转换为object类型,所以当从集合中获取元素时要通过类型转换得到指定类型对象。
示例:
2.3.删除Hashtable的元素:
通过键(key),使用Remove()方法就可以删除。
2.4.遍历Hashtable中的元素
由于Hashtable不能使用索引访问,所以遍历一个Hashtable只能用foreach()方法:
遍历Hashtable中的对象:
四、泛型集合
前面介绍了两种非泛型集合,Hashtable和ArrayList。在实际开发过程中,用的很少了,说明这两个集合也是为了对讲解和学习泛型集合有一个好的铺垫。
非泛型集合对元素的数据类型没有约束性,在添加时数据类型都会被转为Object类型,这意味着集合中可以加入不同的数据类型的数据。那么这样对数据的操作会有什么影响呢?
示例:
在添加的时候没有约束类型,读取的时候也不知道对象的具体的类型,所以在元素数据类型转换的时候就存在了不确定性。有没有什么好的方法限制集合中元素的数据类型呢?下面就来介绍使用泛型集合来保存数据。泛型集合限定了集合中的数据类型。
1.泛型集合List<T>
1.1.语法:List<T> 对象名 = new List<T>();
“<T>”需要指定一个数据类型,将T替换换指定数据类型后就可以对集合中的元素的数据类型进行约束。
1.2.泛型集合List<T>添加、获取、删除元素以及遍历的方法和ArrayList的用法都是类似的。但是List<T>在遍历访问元素时无需做类型转换。
示例:
1.3.List<T>与ArrayList的区别
2.泛型集合Dictionary<K,V>
Dictionary<K,V>集合类似于前面所讲的Hashtable,也是通过Key/value(键/值)对元素保存的。
它具有泛型的全部特性,编译时检查类型约束,获取元素时只能通过key而不能通过索引,并且获取元素时无需类型转换。
2.1.语法:
Dictionary<K,V> 对项目 = new Dictionary<K,V>();
说明:K表示集合中指定Key的类型,V表示Value的类型。他们的含义和List<T>是相同的。
2.2.Dictionary<K,V>集合的常用(添加、删、获取)操作方法和Hashtable是一样的,在这里不详细介绍。
示例:
2.3.遍历Dictionary<K,V>集合:
KeyValuePair<Tkey,Tvalue>是一个泛型结构,定义可设置或者检索的键/值对。详细内容可以查阅MSDN。
2.4.Dictionary<K,V>和Hashtable的对比:
总结:本文只是对集合做了基础和细节的介绍,集合在开发中通常用来存储对象,而在实际的开发中还要结合实际功能深入去学习怎么去运用才是关键。