WPF 基础知识介绍

1. 项目框架

MVVM是Model、View、ViewModel的简写,这种模式的引入就是使用ViewModel来降低View和Model的耦合,说是降低View和Model的耦合。也可以说是是降低界面和逻辑的耦合,理想情况下界面和逻辑是完全分离的,单方面更改界面时不需要对逻辑代码改动,同样的逻辑代码更改时也不需要更改界面。同一个ViewModel可以使用完全不用的View进行展示,同一个View也可以使用不同的ViewModel以提供不同的操作。
Assets
…Fonts
…Images
…Styles
Common(通用类)
Converter(转换器)
DataAccess
Model
View
ViewModel

2. XAML

Window属于ContentControl(内容控件),一个内容控件只能容纳一个内容,如grid
属性:
ShowInTaskbar 窗口是否具有任务栏按钮
WindowStartupLocation 窗口启动位置
WindowState 窗口最大化最小化显示
TopMost     Icon
事件
Loaded
Closing
MouseDoubleClick

2.1. 窗体圆角

更改window 窗体属性AllowTransParency为True,BackGround为Transparent,OpacityMask为White,这样设置才能保证当我们设置为圆角的时候,四个角能够透明显示
只需要在原来的Grid同级加个Border,然后再Grid和Bordr的外层加个Grid即可

BorderThickness用来表示Border的粗细程度,BorderBrush用来表示Border的颜色,CornerRadius表明四个角的弯曲度
WPF 基础知识介绍_第1张图片

2.2. 窗体继承

https://www.cnblogs.com/zhouyinhui/archive/2008/03/16/1108561.html
https://www.cnblogs.com/ApolloSun/archive/2010/03/23/1692744.html

需要单独创建一个资源字典类型的xaml文件和配套的cs文件

2.2. Binding 和 字符串拼接


        
    

2.3. Backgroud Binding 是字符串格式,不是Brush类型

2.4. button圆角



2.5. XML的转义字符

https://www.cnblogs.com/wuzhenyi/archive/2013/01/13/2858797.html

 1. 在XAML的后台文件中加入代码
 Me.TextBlock1.Text = "AAAAAAA " + vbCrLf + "BBBBBBBB"
 this.TextBlock1.Text = "AAAAAAA\nBBBBBBBB";
 2. 前端可以用下面的转义字符
空格 ( ) 
Tab (	) 
回车 (
) 
换行 (
)

2.6. 取消全局样式

https://blog.csdn.net/rrzhaobaojun/article/details/11935157

Style="{x:Null}"取消模版button的style在这个模版里就可以了

2.7. 视觉状态管理器

一个VisualStateGroup里面的VisualState是互斥的

  1. 自定义控件通过下面的方式更改状态
    : VisualStateManager.GoToState(d as NumericBoxControl, “state1”, true);
  2. 在viewmodel 里更改状态
    https://stackoverflow.com/questions/6002046/binding-visualstatemanager-view-state-to-a-mvvm-viewmodel





	
		
			
				
			
		
		
			
				
			
		
	

2.8. Converter

.Net提供了两种Converter接口,单值转换的接口IValueConverter和多值转换的接口IMultiValueConverter,

1. xaml引用命名空间    xmlns:converter="clr-namespace:WpfApp1.Converter"
2. xaml定义resources

    

3. Converter文件夹下添加 GenderConverter.cs 文件,继承IValueConverter接口,实现类
public class GenderConverter : IValueConverter
    {
        //Model 向 View 转换
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || parameter == null)
            {
                return false;
            }
            return value.ToString() == parameter.ToString();
        }

        //View 向 Model 转换
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return parameter;
        }
    }
4. 控件添加Converter

2.9. Animation(动画)

https://blog.csdn.net/ajian11/article/details/82504629

共有三种类型的动画(线性/关键帧/路径),在System.Windows.Media.Animation名称空间中将会发现以下内容:
17个线性插值动画类,这些类使用线性插值动画
22个关键帧动画类,这些类使用关键帧动画
3个路径动画类,这些类使用基于路径的动画

线性动画:在一个开始值和结束值之间以逐步增加的方式(被称为线性插值的过程)改变属性的动画,DoubleAnimation动画类和ColorAnimation动画类属于第一种动画,它们使用插值平滑地改变数值
关键帧动画:从一个值突然改变到另外一个值的动画,所有的关键帧动画类都使用"类型名+AnimationUsingKeyFrames"的形式进行命名,如StringAnimationUsingKeyFrames类和ObjectAnimationUsingKey Frames类
路径的动画:基于路径的动画修改数值使其符合由PathGeometry对象描述的形状,并且它主要用于沿着路径移动元素。基于路径的动画类使用"类型名+AnimationUsingPath"的形式进行命名,如DoubleAnimationUsingPath动画类和PointAnimationUsingPath动画类

WPF 基础知识介绍_第2张图片
例子1
https://blog.csdn.net/weixin_44870681/article/details/93660976

  1. 下添加
 
  
   
   
    
   
   
    
   
	    
	    
   
   
 
  1. 下添加

	

例子2
某个控件沿着规划路径移动


	
	
		
	


	
		
	


	
	
		
			
		
	

2.10. 事件触发器

在Style下的触发器只能操作自身,Style.Triggers
在控件下的触发器可以操作同级的控件,控件.Triggers

2.11. 定义系统的整体颜色方案

https://blog.csdn.net/weixin_43876816/article/details/115694445


	            
		
		


 

2.12. listview控件绑定右键菜单命令

https://blog.csdn.net/u014650759/article/details/103722164

2.13. 拖动改变ListView行数据顺序

https://www.cnblogs.com/zhangyongheng/p/4065427.html

2.14. ListViewItem双击事件绑定到Command

https://www.cnblogs.com/yang-fei/p/5419000.html

2.15. ListView根据显示内容更改行的背景色

https://www.cnblogs.com/changbaishan/p/3308045.html


    

2.16. ListView根据显示内容更改ContextMenu MenuItem


	
		

	
	
	
		
			
			
		
	

2.20. GridView的列宽度设置为按比例分配


    
        
            
            
            
            
        
        
        
        
        
    
    
        
            
                
                
                
                
            
        
    

2.30. TreeView 获取TreeViewItem

通过toolsTree_Selected事件获取

private void toolsTree_Selected(object sender, RoutedEventArgs e)
{
	TreeViewItem treeViewItem = e.OriginalSource as TreeViewItem;
	if (treeViewItem == null || e.Handled) return;
	treeViewItem.IsExpanded = !treeViewItem.IsExpanded;
	//treeViewItem.IsSelected = false;
	e.Handled = true;
}

2.31. Tree

3. 基础设置

   无边框,无背景

**窗体四周小边框**

   
        
    


3.1WPF关闭应用程序,释放Window窗口资源方法

https://blog.csdn.net/hujianwind/article/details/9351183

WindowsForm里一个Application.Exit();方法就可以关闭应用程序,释放掉资源。
WPF里Application类没有该方法,但是有一个Exit的事件驱动,在WPF应用程序里面关闭程序讲究很多:
在WPF应用程序的关闭是有ShutdownMode属性设置,具有3中枚举类型的值:
1)OnLastWindowClose 应用程序最后一个窗体关闭时关闭应用程序
2)OnMainWindowClose 应用程序主窗体关闭时关闭应用程序
3)OnExplicitShutdown 显示调用关闭
在OnExplicitShutdown模式下必须显示调用Application实例的ShutDown方法

3.2 DataGrid
3.2.1 表格按钮绑定事件
传的参数为当前行

    
        
            
3.2.2 获取 DataTemplate 里面的控件
DataGrid dataGrid = (DataGrid)obj;

DataGridTemplateColumn templeColumn = dataGrid.Columns[0] as DataGridTemplateColumn;

FrameworkElement element;
CheckBox checkBox;

for(int i = 0; i < dataGrid.Items.Count; i++)
{
	element = dataGrid.Columns[0].GetCellContent(dataGrid.Items[i]);
	checkBox = templeColumn.CellTemplate.FindName("checkPDU", element) as CheckBox;
	Console.WriteLine(checkBox.IsChecked.ToString());
}
3.2.3 绑定ItemsSource=“{Binding Collection,Mode=TwoWay}”

数据源的绑定方式是OneWay, 前端更改了数据,是不能同步到后端的,
如果需要同步到后端,可以在具体的cell 添加UpdateSourceTrigger=PropertyChanged,比如下面的
IsChecked=“{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}”

3.2.4 自动滚动到最新行
public OneDimensionalCodeFuncView()
 {
      InitializeComponent();
      ((ICollectionView)this.DataGridOneDC.Items).CollectionChanged += QueryBusinessLevelWindow_CollectionChanged;
  }

  private void QueryBusinessLevelWindow_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  {
      if (e.NewItems != null)//新增数据时才出发滚动
          this.DataGridOneDC.ScrollIntoView(this.DataGridOneDC.Items[this.DataGridOneDC.Items.Count - 1]);
  }
3.2.5 采用handycontrol的样式
添加样式资源,一般是在App.xaml里添加,如果样式被覆盖了,可以在DataGrid所在的xaml页面添加




居中的样式








    


3.3 MouseLeftButtonDown事件失效的问题

控件在捕获了MouseLeftButtonDown事件后,会将该事件的“Handled”设置为True,这个属性是用在事件路由中的,当某个控件得到一个RoutedEvent,就会检测Handled是否为true,为true则忽略该事件。
并且,控件本身的Click事件,相当于将MouseLeftButtonDown事件抑制(Supress)掉了,转换成了Click事件。所以,如果一定要使用这个事件的话,需要在初始化的函数里利用UIElement的AddHandler方法,显式的增加这个事件

 public MainWindow()
        {
            InitializeComponent();
            button_get_trade_record.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.button_get_trade_record_MouseLeftButtonDown), true);
        }

3.4 绑定用户控件中某控件的属性

https://www.bilibili.com/video/BV1UE411R7g2?p=8
使用依赖属性

3.5 播放flash动画

https://www.bilibili.com/video/BV1UE411R7g2?p=7

3.6 绑定跟踪调试

https://www.bilibili.com/video/BV1UE411R7g2?p=6

在引用里添加 xmlns:dbg=“clr-namespace:System.Diagnostics;assembly=WindowBase”

3.7 动态的复制粘贴控件

https://www.bilibili.com/video/BV1UE411R7g2?p=3

3.8 为粘贴的控件添加事件

https://www.bilibili.com/video/BV1UE411R7g2?p=6

3.9 WPF使用winform的控件

https://cloud.tencent.com/developer/article/1760996

3.10 ViewModel里获取View 里的控件对象
1. 通过loaded事件获取(下面的例子因为使用了WindowsFormsHost,不能直接绑定WindowsFormsHost下面的控件ElementName,需要先绑定WindowsFormsHost,然后通过child获取)
xmal

        
            
        
    
viewmodel  
    public RelayCommand LoadedHWCommand { get; set; }
    this.LoadedHWCommand = new RelayCommand(LoadHW);
    private void LoadHW(object o)
        {
            try
            {
                //获取HWindowControlWPF控件对象
                form_Host = (WindowsFormsHost)o;
                hWindow_Fit1 = (HWindow_Final)form_Host.Child;
            }
            catch (Exception)
            {
                throw;
            }
        }
2. 通过按钮的command事件获取
xmal