.NET-7.WPF学习2. 知识总结
前言
对wpf 的知识总结。
一、面试
1. 跨线程操作(Dispatcher)
2. template(模板类型【控件模板、数据模板、面板模板】、逻辑树【UI界面的组成元素】、可视化树【逻辑树的扩展版本,将元素分成更小的部分】)
https://blog.csdn.net/ceasadan/article/details/61414879
3. binding(绑定源、绑定模式【default、OneWay、TwoWay、OntTime、OneWayToSource】、触发绑定更新的事件【Default、Explicit(手动BindingExpression.UpdayeSource())、PropertyChange、LostFocus】、优先级PriorityBinding)
4. trigger(4种,属性触发器,数据触发器,事件触发器,多条件触发器)
5. 解释什么是依赖属性,它和以前的属性有什么不同?为什么在WPF会使用它?
绑定(Binding )的基础用法
//解释这几个类的作用及关系: Visual, UIElement, FrameworkElement, Control
//视觉树vs 逻辑树?
//ResourceDictionary、UserControls (INotifyPropertyChange 和ObservableCollection)
//事件的三种方式(冒泡、直接、隧道)
//Routed Events(路由事件) & Commands (命令)
//绑定详解(包括绑定到单一属性、实体、集合、值转换、触发机制、验证等)
//怎样布局一个漂亮的UI(你们以前的项目是怎么做的?) (原型)
//ClickOnce 部署(优点和缺点)或者是自己通过微软setup/InstallShield+自己的自动更新组件。
https://blog.csdn.net/weixin_30315723/article/details/99666348
// 什么是attached behavior 依赖属性(附加行为或者附加事件)?
//是否使用过?你们是怎么用的?没有使用的话,解释一下自己的开发模式和框架。
(prism ,MVVMLight ,CommunityToolkit.Mvvm,Microsoft.Toolkit.Mvvm ,Caliburn.Micro(简称CM)) --fody
//怎样才能工作线程更新UI?
https://blog.csdn.net/sdhongjun/article/details/82973796
//WPF 3D和动画的应用(是否使用过?用过哪些?)。
//怎么开发自定义控件?可以简单介绍一下自己开发的控件。
1. 自定义控件 button
//三种开发模式(MVVM/MVP/MVC)的理解。
1. 这种模式,view的变化会自动更新到viewmodel,viewmodel的变化也会自动同步到view上显示。
vue和angular、wpf就是MVVM框架的典型代表。
2. MVP是从MVC模式演变而来,presenter(负责逻辑的处理),model(数据),view(负责显示)。
3. view一般都是通过controller来和model进行联系,基本联系都是单向的。view就相当是用户界面,比如说用户界面传送指令给controller,它完成业务逻辑之后要求model改变模型,当model发生改变之后,将新的view呈现出来。.net core mvc
//WPF的性能调整(你是怎么优化WPF性能的?)
资源:
1、 通常情况下我们会把样式资源都统一到App.xaml中,这是很好的,便于资源的管理。
2、 尽量把多次重复用到的资源放到App.xaml中。例如某些页面的资源只会在当前页面中使用到,那么可以把资源定义在当前页面; 因为放在控件中会使每个实例都保留一份资源的拷贝。
3、 如非必要,不要使用DynaicResource,使用StaticResource即可;
//聊聊你做WPF的一些经验和体会。
1. wpf的优点、缺点:
- 事件驱动,数据驱动(强大的 “数据绑定”功能,使得MVVM得以实现 mvvm模式)
- WPF是基于Direct3D创建。做出更加绚丽的效果
- WPF是基于矢量绘图的,因此它产生的图形界面能够支持各种分辨率的显示设备,
- 占用的资源太多 内存占用和性能要求较高
- 较高的学习成本
二、代码片段
//1. ListView,datagrid绑定dataset
<DataGrid Grid.Column="1" Grid.Row="1" Name="datagrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="订单号" Binding="{Binding OrderNo}"/>
<DataGridTextColumn Header="订单状态" Binding="{Binding OrderStatus}" />
<!--The Email property contains a URI. For example "mailto:lucy0@adventure-works.com"-->
<DataGridHyperlinkColumn Header="计划生产时间" Binding="{Binding OrderTime}" />
</DataGrid.Columns>
</DataGrid>
this.datagrid.DataContext = dataset.Tables[0];//绑定table||list<User>
<ListView Grid.Row="1" Name="listview" ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="订单号" DisplayMemberBinding="{Binding OrderNo}"/>
<GridViewColumn Header="订单状态" DisplayMemberBinding="{Binding OrderStatus}"/>
<GridViewColumn Header="计划生产时间" DisplayMemberBinding="{Binding OrderTime}"/>
</GridView>
</ListView.View>
</ListView>
this.listview.DataContext = dataset.Tables[0];
//treeview
<TreeView Name="treeview" Grid.Column="1" ItemsSource="{Binding Path=Nodes}" Width="50">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TreeNode}" ItemsSource="{Binding Path=childnodes}">
<Label Content="{Binding Path=name}"
>
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="FontSize" Value="14"/>
</Style>
</Label.Style>
</Label>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
TreeNode blood = new TreeNode()
{
name = "血液检查",
childnodes=new ObservableCollection<TreeNode>()
{
new TreeNode() { name="zhouyi0"},
new TreeNode() { name="zhouyi1"},
new TreeNode() { name="zhouyi2"},
new TreeNode() { name="zhouyi3"},
}
};
TreeNode cancer = new TreeNode()
{
name = "癌症检查",
childnodes = new ObservableCollection<TreeNode>()
{
new TreeNode() { name="zhouyi0"},
new TreeNode() { name="zhouyi1"},
new TreeNode() { name="zhouyi2"},
new TreeNode() { name="zhouyi3"},
}
};
Nodes = new ObservableCollection<TreeNode>() { blood, cancer };
//-----------
public class TreeNode
{
public string name { get; set; }
public ObservableCollection<TreeNode> childnodes { get; set; }
}
## 窗口永远置顶
<Window
Title="工具条" Width="276" Height="728"
Deactivated="Window_Deactivated"
>
</Window>
PreviewLostKeyboardFocus="Window_PreviewLostKeyboardFocus"
private void Window_Deactivated(object sender, EventArgs e)
{
Window window = (Window)sender;
window.Topmost = true;
Console.WriteLine("工具条窗口置顶");
}
# 分割线
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
//2.(日期)Calendar、DatePicker
<StackPanel Orientation="Horizontal">
<!-- Create a Calendar that displays 1/10/2009
through 4/18/2009. -->
<Calendar Margin="20"
SelectedDate="2/15/2009"
DisplayDate="3/15/2009"
DisplayDateStart="1/10/2009"
DisplayDateEnd="4/18/2009"/>
<!-- Create a Calendar that displays dates through
Januarary 31, 2009 and has dates that are not selectable. -->
<Calendar Margin="20" SelectionMode="MultipleRange"
IsTodayHighlighted="false"
DisplayDate="1/1/2009"
DisplayDateEnd="1/31/2009"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Calendar.BlackoutDates>
<CalendarDateRange Start="1/2/2009" End="1/4/2009"/>
<CalendarDateRange Start="1/9/2009" End="1/9/2009"/>
<CalendarDateRange Start="1/16/2009" End="1/16/2009"/>
<CalendarDateRange Start="1/23/2009" End="1/25/2009"/>
<CalendarDateRange Start="1/30/2009" End="1/30/2009"/>
</Calendar.BlackoutDates>
<Calendar.SelectedDates>
<sys:DateTime>1/5/2009</sys:DateTime>
<sys:DateTime>1/12/2009</sys:DateTime>
<sys:DateTime>1/14/2009</sys:DateTime>
<sys:DateTime>1/13/2009</sys:DateTime>
<sys:DateTime>1/15/2009</sys:DateTime>
<sys:DateTime>1/27/2009</sys:DateTime>
<sys:DateTime>4/2/2009</sys:DateTime>
</Calendar.SelectedDates>
</Calendar>
</StackPanel>
//-------------------
<!-- A DatePicker that has March 23, 2009 selected and
displays the Long date format. -->
<DatePicker SelectedDateFormat="Long" SelectedDate="3/23/09"
DisplayDateStart="1/01/09" DisplayDateEnd="12/31/09"
FirstDayOfWeek="Monday"/>
//3. (导航) Frame、Hyperlink、Page、NavigationWindow、TabControl
//Frame
<Frame Name="islandFrame" Source="IslandFrameContent.xaml" />
//Hyperlink
<Paragraph>
<Run>Text preceding the hyperlink.</Run>
<Hyperlink
NavigateUri="http://search.msn.com"
>
Link text.
</Hyperlink>
<Run Name="test">Text following the hyperlink.</Run>
</Paragraph>
//NavigationWindow
<NavigationWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MainWindow"
Title="NavigationWindow Sample"
Source="http://www.microsoft.com" />
//TabControl
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Ellipse Width="10" Height="10" Fill="DarkGray"/>
<TextBlock>Tab 1</TextBlock>
</StackPanel>
</TabItem.Header>
<StackPanel>
<TextBlock>Enter some text</TextBlock>
<TextBox Name="textBox1" Width="50"/>
</StackPanel>
</TabItem>
<TabItem Header="Tab 2">
<!--Bind TextBlock.Text to the TextBox on the first
TabItem.-->
<TextBlock Text="{Binding ElementName=textBox1, Path=Text}"/>
</TabItem>
</TabControl>
//5. BulletDecorator
- BulletDecorator表示一个布局控件,该控件将项目符号与另一个可视对象对齐。
<BulletDecorator Grid.Row="1" Grid.Column="0" Margin="0,5,0,0"
VerticalAlignment="Center" Background="Yellow">
<BulletDecorator.Bullet>
<Image Source="images\apple.jpg"/>
</BulletDecorator.Bullet>
<TextBlock
Width="100"
TextWrapping="Wrap"
HorizontalAlignment="Left"
Foreground ="Purple">
A Simple BulletDecorator
</TextBlock>
</BulletDecorator>
//6. 数据绑定
>0.
Mode=OneWay 源改变他变
this.textBox1.SetBinding(TextBox.TextProperty, new Binding("Value") {Source=slider1,Mode=BindingMode.OneWay});
Text="{Binding Path=Value,ElementName=slider1,Mode=OneWay}"
>binding 文本 参数
>1.
this.textBox2.SetBinding(TextBox.TextProperty, new Binding("Text.[3]") { Source=textBox1,Mode= BindingMode.OneWay});
<TextBox Height="23" HorizontalAlignment="Left" Margin="152,50,0,0" Name="textBox1" VerticalAlignment="Top" Width="158" Text="ABCDE" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="152,105,0,0" Name="textBox2" Text="{Binding Path=Text.[1],ElementName=textBox1,Mode=OneWay}" VerticalAlignment="Top" Width="158"/>
>2.
List<string> infos = new List<string>() { "Jim","Darren","Jacky"};
textBox1.SetBinding(TextBox.TextProperty, new Binding("/") { Source=infos});
textBox2.SetBinding(TextBox.TextProperty, new Binding("/[0]") { Source = infos, Mode= BindingMode.OneWay });
textBox3.SetBinding(TextBox.TextProperty, new Binding("/Length") { Source = infos, Mode= BindingMode.OneWay });
<TextBox Height="23" Name="textBox1" Width="120" Margin="10" />
<TextBox Height="23" Name="textBox2" Width="120" Margin="10" />
<TextBox Height="23" Name="textBox3" Width="120" Margin="10" />
>3.
List<Contry> infos = new List<Contry>() { new Contry() { Name = "中国", Provinces= new List<Province>(){ new Province(){ Name="四川",Citys=new List<City>(){new City(){Name="绵阳市"}}}}}};
this.textBox1.SetBinding(TextBox.TextProperty, new Binding("/Name") { Source=infos});
this.textBox2.SetBinding(TextBox.TextProperty, new Binding("/Provinces/Name") { Source = infos });
this.textBox3.SetBinding(TextBox.TextProperty, new Binding("/Provinces/Citys/Name") { Source = infos });
class City
{public string Name { set; get; }}
class Province
{
public string Name { set; get; }
public List<City> Citys { set; get; }
}
class Contry
{
public string Name { set; get; }
public List<Province> Provinces { get; set; }
}
>4.
<StackPanel.Resources>
<String:String x:Key="myString">
菩提本无树,何处染尘埃。
</String:String>
</StackPanel.Resources>
<TextBlock Height="23" Name="textBlock1" Text="{Binding Path=.,Source={StaticResource ResourceKey=myString}}" />
string myString = "菩提本无树,明镜亦无台。本来无一物,何处染尘埃。";
this.textBlock1.SetBinding(TextBlock.TextProperty, new Binding(".") { Source=myString});
>5.
<StackPanel Background="AliceBlue">
<StackPanel.DataContext>
<Stu:Student Id="1" Name="Darren" Age="10"></Stu:Student>
</StackPanel.DataContext>
<Grid>
<StackPanel Height="283" HorizontalAlignment="Left" Margin="12,12,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="418">
<TextBox Height="23" Name="textBox1" Width="120" Margin="15" Text="{Binding Path=Id}"/>
<TextBox Height="23" Name="textBox2" Width="120" Margin="15" Text="{Binding Path=Name}"/>
<TextBox Height="23" Name="textBox3" Width="120" Margin="15" Text="{Binding Path=Age}"/>
</StackPanel>
</Grid>
</StackPanel>
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
>6.
<Grid.DataContext>
<Str:String>Hello DataContext</Str:String>
</Grid.DataContext>
<StackPanel>
<TextBlock Height="23" HorizontalAlignment="Left" Margin="15" Name="textBlock1" Text="{Binding}" VerticalAlignment="Top" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="15" Name="textBlock2" Text="{Binding}" VerticalAlignment="Top" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="15" Name="textBlock3" Text="{Binding}" VerticalAlignment="Top" />
</StackPanel>
>7.
<StackPanel Height="295" HorizontalAlignment="Left" Margin="10,10,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="427">
<TextBlock Height="23" Name="textBlock1" Text="学员编号:" />
<TextBox Height="23" Name="txtStudentId" Width="301" HorizontalAlignment="Left"/>
<TextBlock Height="23" Name="textBlock2" Text="学员列表:" />
<ListBox Height="156" Name="lbStudent" Width="305" HorizontalAlignment="Left">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="stackPanel2" Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Margin="5" Background="Beige"/>
<TextBlock Text="{Binding Name}" Margin="5"/>
<TextBlock Text="{Binding Age}" Margin="5"/>
<Button Content="zhouyi"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Button" Height="23" Name="button1" Width="75" HorizontalAlignment="Left" Click="button1_Click" />
</StackPanel>
ObservableCollection<Student> infos = new ObservableCollection<Student>() {
new Student(){ Id=1, Age=11, Name="Tom"},
new Student(){ Id=2, Age=12, Name="Darren"},
new Student(){ Id=3, Age=13, Name="Jacky"},
new Student(){ Id=4, Age=14, Name="Andy"}
};
this.lbStudent.ItemsSource = infos;
this.txtStudentId.SetBinding(TextBox.TextProperty,new Binding("SelectedItem.Id"){ Source=lbStudent});}
private void button1_Click(object sender, RoutedEventArgs e)
{infos[2].Name = "付文军";}
>8. gridview
<StackPanel Height="279" Name="stackPanel1" Width="431">
<ListView Height="247" Name="listView1" Width="376">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="60">
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="60">
</GridViewColumn>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="60">
</GridViewColumn>
<GridViewColumn Header="Sex" DisplayMemberBinding="{Binding Sex}" Width="60">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
DataTable dtInfo = CreateDataTable();
for (int i = 0; i < 10; i++)
{
DataRow dr = dtInfo.NewRow();
dr[0] = i;
dr[1] = "猴王" + i;
dr[2] = i + 10;
dr[3] = "男";
dtInfo.Rows.Add(dr);
}
this.listView1.DataContext = dtInfo;
this.listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());
private DataTable CreateDataTable()
{
DataTable dt = new DataTable("newtable");
DataColumn[] columns = new DataColumn[]{new DataColumn("Id"),new DataColumn("Name"),new DataColumn("Age"),new DataColumn("Sex")};
dt.Columns.AddRange(columns);
return dt;
}
>9. 读取xml文件
<StackPanel Width="409" Height="331" Background="LightBlue">
<ListView Height="302" Name="listView1" Width="396">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding XPath=@id}" Width="80">
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=Name}" Width="150">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
private void BindingInfo()
{
XmlDataProvider dp = new XmlDataProvider();
dp.Source = new Uri(@"E:\Desktop\srqcwpfwzb_downcc.com\WpfApplication1\StudentData.xml");
dp.XPath = @"StudentList/Student";
this.listView1.DataContext = dp;
this.listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());
}
---<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
<Student id="1">
<Name>Andy</Name>
</Student>
<Student id="2">
<Name>Jacky</Name>
</Student>
<Student id="3">
<Name>Darren</Name>
</Student>
<Student id="4">
<Name>DK</Name>
</Student>
<Student id="5">
<Name>Jim</Name>
</Student>
</StudentList>
>10. treeview /xml
<Window.Resources>
<XmlDataProvider x:Key="xdp" XPath="FileSystem/Folder">
<x:XData>
<FileSystem xmlns="">
<Folder Name="Books">
<Folder Name="Programming">
<Folder Name="Windows">
<Folder Name="WPF">
</Folder>
<Folder Name="Winform">
</Folder>
<Folder Name="ASP.NET">
</Folder>
</Folder>
</Folder>
</Folder>
<Folder Name="Tools">
<Folder Name="Development"/>
<Folder Name="Designment"/>
<Folder Name="Players"/>
</Folder>
</FileSystem>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<Grid>
<TreeView Height="283" HorizontalAlignment="Left" Name="treeView1" VerticalAlignment="Top" Width="511" ItemsSource="{Binding Source={StaticResource ResourceKey=xdp}}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=Folder}">
<TextBlock Height="23" HorizontalAlignment="Left" Name="textBlock1" Text="{Binding XPath=@Name}" VerticalAlignment="Top" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
>11 三种数据绑定的方法
<Grid>
<ListView Height="311" HorizontalAlignment="Left" Margin="10,10,0,0" Name="listView1" VerticalAlignment="Top" Width="494">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="100"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100"/>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="100"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
private void BindingDataByCLR()
{
List<Student> infos = new List<Student>()
{
new Student(){Id=1, Age=29, Name="Tim"},
new Student(){Id=1, Age=28, Name="Tom"},
new Student(){Id=1, Age=27, Name="Kyle"},
new Student(){Id=1, Age=26, Name="Tony"},
new Student(){Id=1, Age=25, Name="Vina"},
new Student(){Id=1, Age=24, Name="Mike"}
};
this.listView1.ItemsSource = from stu in infos where stu.Name.StartsWith("T") select stu;
}
private void BindingDataByDataTable()
{
DataTable dtInfo = CreateDataTable();
this.listView1.ItemsSource = from row in dtInfo.Rows.Cast<DataRow>()
where Convert.ToString(row["Name"]).StartsWith("T")
select new Student()
{
Id = Convert.ToInt32(row["Id"]), Name=Convert.ToString(row["Name"]),Age=Convert.ToInt32(row["Age"])
};
}
private void BindingDataByXml()
{
XDocument xd = XDocument.Load(@"E:\Desktop\srqcwpfwzb_downcc.com\WpfApplication1\testDate.xml");
this.listView1.ItemsSource = from element in xd.Descendants("Student")
where element.Attribute("Name").Value.StartsWith("T")
select new Student()
{
Name = element.Attribute("Name").Value,
Id = Convert.ToInt32(element.Attribute("Id").Value),
Age = Convert.ToInt32(element.Attribute("Age").Value)
};
}
private DataTable CreateDataTable()
{
DataTable dt = new DataTable("newtable");
DataColumn[] columns = new DataColumn[] { new DataColumn("Id"), new DataColumn("Name"), new DataColumn("Age")};
dt.Columns.AddRange(columns);
return dt;
}
>12 ObjectDataProvider
private void button1_Click(object sender, RoutedEventArgs e)
{
ObjectDataProvider odp = new ObjectDataProvider();
odp.ObjectInstance = new Caculate();
odp.MethodName = "Add";
odp.MethodParameters.Add("300");
odp.MethodParameters.Add("200");
MessageBox.Show(odp.Data.ToString());
}
public class Caculate
{
public string Add(string arg1,string arg2)
{
double x = 0;
double y = 0;
double z = 0;
if(double.TryParse(arg1,out x)&&double.TryParse(arg2,out y))
{
z = x + y;
return z.ToString();
}
return "Iput Error";
}
//其它方法省略
}
>13 ObjectDataProvider two
<StackPanel Background="LightBlue">
<TextBox Height="23" Name="textBox1" Width="200" HorizontalAlignment="Left" Margin="15" Text="0"/>
<TextBox Height="23" Name="textBox2" Width="200" HorizontalAlignment="Left" Margin="15" Text="0"/>
<TextBox Height="23" Name="textBox3" Width="200" HorizontalAlignment="Left" Margin="15"/>
</StackPanel>
private void SetBinding()
{
ObjectDataProvider objpro = new ObjectDataProvider();
objpro.ObjectInstance = new Caculate();
objpro.MethodName = "Add";
objpro.MethodParameters.Add("0");
objpro.MethodParameters.Add("0");
Binding bindingToArg1 = new Binding("MethodParameters[0]") { Source=objpro,BindsDirectlyToSource=true, UpdateSourceTrigger= UpdateSourceTrigger.PropertyChanged};
Binding bindingToArg2 = new Binding("MethodParameters[1]") { Source=objpro,BindsDirectlyToSource=true,UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged};
Binding bindToResult = new Binding(".") { Source=objpro};
this.textBox1.SetBinding(TextBox.TextProperty, bindingToArg1);
this.textBox2.SetBinding(TextBox.TextProperty, bindingToArg2);
this.textBox3.SetBinding(TextBox.TextProperty,bindToResult);
}
>14 RelativeSource属性
RelativeSource rs = new RelativeSource(RelativeSourceMode.Self);
Binding bind = new Binding("Name") { RelativeSource = rs };
this.textBox1.SetBinding(TextBox.TextProperty, bind);
<TextBox Name="textBox1" Margin="10" FontSize="24" Text="{Binding Path=Name, RelativeSource={RelativeSource Mode=Self}}"/>
9. 资源字典
-. 定义一个资源字典,Dictionary.xaml
-. App.xaml 里面实现全局样式
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="solidColor" Color="Red"/>
<Style x:Key="buttonStyleBase" TargetType="Button">
<Setter Property="FontSize" Value="25"/>
<Setter Property="Background" Value="Red"/>
</Style>
<Style x:Key="buttonStyle" TargetType="Button" BasedOn="{StaticResource buttonStyleBase}">
<Setter Property="Margin" Value="20"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
//代码找到资源
this.Resources["solidColor"]=new SolidColorBrush(Colors.Yellow);
var style = App.Current.Resources["solidColor"];
var style1 = App.Current.FindResource("SolidColor");
10.动画
private void btn_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = btn.Width;//起始值
doubleAnimation.To = btn.Width + 30;//结束值
//doubleAnimation.By=-30;//结束值
doubleAnimation.AutoReverse = true;//自动toggle
//doubleAnimation.RepeatBehavior=RepeatBehavior.Forever;//无限执行
doubleAnimation.RepeatBehavior=new RepeatBehavior(2);//执行2次
doubleAnimation.Duration = TimeSpan.FromSeconds(2);
doubleAnimation.Completed += DoubleAnimation_Completed;
btn.BeginAnimation(Button.WidthProperty, doubleAnimation);
}
private void DoubleAnimation_Completed(object? sender, EventArgs e)
{
MessageBox.Show("Animation Completed!");
}
11.数据模板
<StackPanel>
<ListBox x:Name="list">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Width="100" Background="Red"/>
<TextBlock Margin="20" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<DataGrid x:Name="grid" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="id"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
<DataGridTemplateColumn Header="操作">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="删除"/>
<Button Content="编辑"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
List<Student> students = new List<Student>() { new Student
{
Id = 1,
Name="aaaaaaa"
},new Student
{
Id = 2,
Name="bbbbbbb"
},new Student
{
Id = 3,
Name="cccccc"
} };
list.ItemsSource=students;
grid.ItemsSource = students;
12. 命令绑定和消息通知
<StackPanel>
<TextBox x:Name="aaa" Text="{Binding Name}"/>
<Button Content="消息通知" Command="{Binding MyCommand}"/>
</StackPanel>
this.DataContext = new DataModelView();
class DataModelView: INotifyPropertyChanged
{
public MyCommand MyCommand { get; set; }
private string name;
public string Name {
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
public DataModelView()
{
Name = "zhouyi";
MyCommand=new MyCommand(show);
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string v)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v));
}
public void show()
{
Name = "zhouyichange";
MessageBox.Show("zhouyi");
}
}
class MyCommand : ICommand
{
public event EventHandler? CanExecuteChanged;
Action Action;
public MyCommand(Action action)
{
Action = action;
}
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
Action();
}
}
// 稍微改进 继承BaseNotify 、省去参数OnPropertyChanged();
class BaseNotify : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string v="")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v));
}
}
//1.为WPF应用程序设置渐变的背景颜色
this.Background = (Brush)TryFindResource("MyGradientBackground");
<Window.Resources>
<LinearGradientBrush x:Key="MyGradientBackground"
StartPoint="0,0"
EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0"/>
<GradientStop Color="Red" Offset="0.25"/>
<GradientStop Color="Blue" Offset="0.75"/>
<GradientStop Color="LimeGreen" Offset="1.0"/>
</LinearGradientBrush>
</Window.Resources>
//3. ListView显示DataGrid
<ListView Name="receiveList" Grid.Row="0">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="发件人"
Width="200"
DisplayMemberBinding="{Binding Path=Senderuser}" />
<GridViewColumn Header="主题"
Width="350"
DisplayMemberBinding="{Binding Path=Topic}" />
<GridViewColumn Header="附件" DisplayMemberBinding="{Binding Path=Ffile}"
Width="200" />
<GridViewColumn Header="时间" Width="150" DisplayMemberBinding="{Binding Path=Time}"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
//4. DataTable绑定到DataGrid
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="5,5" Name="dataGrid1" VerticalAlignment="Stretch" ItemsSource="{Binding}" HorizontalGridLinesBrush="Gainsboro" VerticalGridLinesBrush="Gainsboro">
<DataGrid.Columns>
<DataGridTextColumn Header=" ID " Binding="{Binding ID}" ></DataGridTextColumn>
<DataGridTextColumn Header="姓 名" Width ="100" Binding="{Binding Name}" ></DataGridTextColumn>
<DataGridTextColumn Header="电 话" Width ="100" Binding="{Binding PhoneNumber}" ></DataGridTextColumn>
<DataGridTextColumn Header="住 址" Width ="100" Binding="{Binding Address}" ></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
DataTable dt = new System.Data.DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("PhoneNumber", typeof(string));
dt.Columns.Add("Address", typeof(string));
DataRow row = dt.NewRow();
row["ID"] = 1;
row["Name"] = "张三";
row["PhoneNumber"] = "239456";
row["Address"] = "北京";
dt.Rows.Add(row);
row = dt.NewRow();
row["ID"] = 2;
row["Name"] = "李四";
row["PhoneNumber"] = "982089*5";
row["Address"] = "广东";
dt.Rows.Add(row);
dataGrid1.ItemsSource = dt.DefaultView;
dataGrid1.GridLinesVisibility = DataGridGridLinesVisibility.All;////设置网格线
//5. 上下拉分隔符效果
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="150" />
</Grid.RowDefinitions>
<Rectangle Height="16" VerticalAlignment="bottom">
<Shape.Fill>
<RadialGradientBrush>
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.019230769230769232" Color="sc#0.300000, 0.000000, 0.000000, 0.000000" />
<GradientStop Offset="1" Color="#FFFFFFFF" />
</GradientStopCollection>
</GradientBrush.GradientStops>
<Brush.RelativeTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<TranslateTransform X="-0.0052816901408450721" Y="0.5185185185185186" />
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Brush.RelativeTransform>
</RadialGradientBrush>
</Shape.Fill>
</Rectangle>
<Button
Grid.Row="0"
Content="demo"
Template="{StaticResource ButtonTemplate1}" />
<GridSplitter
Width="Auto"
Height="15"
Margin="10,0,10,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="White"
Cursor="SizeNS"
Opacity="0" />
<Button Grid.Row="1" Content="dmeo" />
</Grid>
//99. 动画
1. DoubleAnimation 创建两个双精度值之间的转换:
<DoubleAnimation From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"/>
var myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
2. 若要向对象应用动画,请创建 Storyboard 并使用
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
private Storyboard myStoryboard;
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
3. xaml
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
- 注册矩形的 Loaded 事件。
myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);
private void myRectangleLoaded(object sender, RoutedEventArgs e)
{
myStoryboard.Begin(this);
}
三、查看链接
//1. wpf图片的预览,以流的方式将图片保存在数据库中,从数据库中读取显示图片
https://www.cnblogs.com/nghygaojun/archive/2013/05/12/3073918.html
BitmapImage tt1 =(BitmapImage)drawViewer.BackgroundImage;
Uri uri = tt1.UriSource;var tt2 = uri.OriginalString;
//2. C# Bitmap 转为位图、 ImageSource 转为Bitmap、Bitmap 转 BitmapImage、BitmapImage 转为byte[]、图片压缩 C# bitmap转换bitmapsource、C# Media.ImageSource类代码示例
https://www.cnblogs.com/lipengxu/p/15734297.html
https://blog.csdn.net/cwt19902010/article/details/78123510
https://vimsky.com/examples/detail/csharp-ex-System.Windows.Media-ImageSource---class.html
//3.实现截图
https://blog.csdn.net/u013113678/article/details/125567308
//4. C# winform、wpf程序中的保留上次记录
https://blog.csdn.net/u011360395/article/details/48177169
//5.用WPF 打开各种对话框
https://blog.csdn.net/elsemind/article/details/8753741
https://blog.csdn.net/weixin_38950569/article/details/125200602
//6. WPF 的彩虹文字
https://www.cnblogs.com/dino623/tag/WPF/ 好的博客在
https://www.cnblogs.com/dino623/p/wpf_rainbow_text.html
//7. 窗体之间的传值
https://blog.csdn.net/qq_38763437/article/details/120716300
http://t.zoukankan.com/kennyliu-p-7017104.html
https://www.cnblogs.com/Leozi/p/10834765.html
//8. 更换主题 HandyControl
https://blog.csdn.net/qq_28806349/article/details/119057529
SkinViolet SkinDark SkinDefault
//9.寻找子控件
http://t.zoukankan.com/mqxs-p-9599375.html
//10.参考图片浏览器(具有参考意义的项目)
https://gitee.com/ShareCodeSite/imagebrowser/repository/archive/master.zip
https://github.com/HeBianGu/WPF-ImagePlayer
https://github.com/HeBianGu/WPF-ControlBase
//11.NET Core 开源工具 IPTools - 快速查询 IP 地理位置、经纬度信息
https://www.cnblogs.com/stulzq/p/9502936.html
//12.轮播图
https://www.bilibili.com/video/BV1av411L7x9/
//13.数据绑定
https://www.jb51.net/article/235833.htm
//14.附加属性;路由事件、附加事件
https://www.cnblogs.com/bruce1992/p/14906040.html
https://blog.csdn.net/hd51cc/article/details/116912540
//15.Ellipse详解
https://blog.csdn.net/BYH371256/article/details/125345247
深入浅出wpf
https://www.cnblogs.com/prism
ObjectDataProvider
https://www.cnblogs.com/T-ARF/p/12369534.html
RelativeSourchttps://blog.csdn.net/yangwenxue1989/article/details/81624240
WPF使用鼠标滚轮和Ctrl实现缩放和放大功能
https://blog.csdn.net/yasenRK/article/details/104769288/
拖拽Image图片控件
https://wenku.baidu.com/view/3007e9034835eefdc8d376eeaeaad1f3469311ad.html
该控件必须要在Canvas的子控件才能设置相关。
>
https://www.cnblogs.com/killmyday/archive/2009/10/28/1591755.html
https://blog.csdn.net/songhuangong123/article/details/126248847
https://www.cnblogs.com/DebugLZQ/archive/2013/05/07/3062733.html
https://www.cnblogs.com/younShieh/p/10811456.html
https://www.pianshen.com/article/7400580805/
https://download.csdn.net/download/kongxh_1981/9161521
https://blog.csdn.net/elie_yang/article/details/78826738
http://t.zoukankan.com/javawebsoa-p-2457963.html
> 图片的方法的放大缩小
http://t.zoukankan.com/GaoHao518-p-14889126.html
> 动画:
https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/graphics-multimedia/animation-overview?view=netframeworkdesktop-4.8
// wpf窗口区域截图
https://www.cnblogs.com/ives/p/printscreen.html
// wpf 打包为exe或者msi的安装程序
https://blog.csdn.net/roujian0985/article/details/123543005
//WPF渐变淡入淡出
https://www.cnblogs.com/zc-bao/p/15476670.html
//WPF换肤之五:创建漂亮的窗体
http://t.zoukankan.com/scy251147-p-2619185.html
//WPF修改窗体标题栏的颜色
https://blog.csdn.net/zls365365/article/details/122207290
//Net插件编程模型:MEF和MAF
https://blog.csdn.net/ghostbear/article/details/7328462
//postgresql 安装
https://blog.csdn.net/qq_45752401/article/details/125083259?
//获取照片的创建的时间
https://blog.csdn.net/biyusr/article/details/125069067
https://www.cnblogs.com/lxshanye/p/4072195.html
private List<string> GetPropertyItems(string fileName)
{
List<string> result = new List<string>(0);
if (File.Exists(fileName))
{
FileStream fm = new FileStream(fileName, FileMode.Open);
//添加访问类型,只读,可能会发生异常,进程被占用。
//FileStream Mystream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
Image Img = Image.FromStream(fm);
foreach (PropertyItem i in Img.PropertyItems)
{
//如果不清楚PropertyItem的Id可以通过枚举获得
//Console.WriteLine("Value:{0},ID:{1}",Encoding.Unicode.GetString(i.Value),i.Id);
var x = i.ToString();
result.Add(Encoding.ASCII.GetString(i.Value));
if (i.Id== 0x0132)
{
createTime = Encoding.ASCII.GetString(i.Value);
}
}
fm.Dispose();
Img.Dispose();
}
return result;
}
---