.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;设置网格线



//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;
}
---






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

joyyi9

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

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

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

打赏作者

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

抵扣说明:

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

余额充值