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表明四个角的弯曲度
在这里插入图片描述

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 和 字符串拼接
<Grid>
        <TextBlock HorizontalAlignment="Left" Margin="51,114,0,0" TextWrapping="Wrap" Text="{Binding Text, ElementName=textBox, StringFormat=Test:\{0\}}" VerticalAlignment="Top"/>
    </Grid>
2.3. Backgroud Binding 是字符串格式,不是Brush类型

https://blog.csdn.net/jolieLi2019888/article/details/89248418

<Button Content="{Binding BtnTestContent}" Command="{Binding StartTestCommand}" Background="{Binding BtnTestBackground}"/>
BtnTestBackground = "#673AB7";
2.4. button圆角
<!--按钮-->
<Button Grid.Row="3" Grid.Column="2" Content="取消" Margin="30,40,200,40" >
	<Button.Template >
		<ControlTemplate TargetType="{x:Type Button}" >
			<Border BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="1" CornerRadius="7,7,7,7">
				<Border.Background>#FFDDDDDD</Border.Background>
				<ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" ></ContentPresenter>
			</Border>
		</ControlTemplate>
	</Button.Template>
</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. 前端可以用下面的转义字符
空格 (&#x0020;) 
Tab (&#x0009;) 
回车 (&#x000D;) 
换行 (&#x000A;)
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
    <i:Interaction.Triggers>
    <ei:DataTrigger Binding=“{Binding StatusName}” Value=“{Binding StatusName}”>
    <ei:GoToStateAction StateName=“{Binding StatusName}” />
    </ei:DataTrigger>
    </i:Interaction.Triggers>
<VisualStateManager.VisualStateGroups>
	<VisualStateGroup>
		<VisualState x:Name="state1">
			<Storyboard>
				<ColorAnimation
					Storyboard.TargetName="PART_Value"
					Storyboard.TargetProperty="Foreground.Color"
					To="Green"
					Duration="0:0:0.1" />
			</Storyboard>
		</VisualState>
		<VisualState x:Name="state2">
			<Storyboard>
				<ColorAnimation
					Storyboard.TargetName="PART_Value"
					Storyboard.TargetProperty="Foreground.Color"
					To="Red"
					Duration="0:0:0.1" />
			</Storyboard>
		</VisualState>
	</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
2.8. Converter

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

1. xaml引用命名空间    xmlns:converter="clr-namespace:WpfApp1.Converter"
2. xaml定义resources
<Window.Resources>
    <converter:GenderConverter x:Key="genderConverter" />
</Window.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
<RadioButton
        IsChecked="{Binding UserInfo.Gender, Converter={StaticResource genderConverter}, ConverterParameter=1}" />
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动画类

在这里插入图片描述
例子1
https://blog.csdn.net/weixin_44870681/article/details/93660976

  1. 在<Window.Resources>下添加
 <Storyboard x:Key="sbkey">
  <!--线性-->
   <DoubleAnimation From="1.0" To="0.0" Duration="0:0:1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Opacity">
   </DoubleAnimation>
    <!--线性-->
   <ColorAnimation From="White" To="Orange" Duration="0:0:2" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background">
   </ColorAnimation>
    <!--离散-->
   <ColorAnimationUsingKeyFrames
	RepeatBehavior="Forever"
	Storyboard.TargetName="StatusLED"
	Storyboard.TargetProperty="Fill.Color">
	    <DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="Green" />
	    <DiscreteColorKeyFrame KeyTime="0:0:1" Value="Gray" />
   </ColorAnimationUsingKeyFrames>
   
 </Storyboard>
  1. 在<Window.triggers>下添加
<EventTrigger RoutedEvent="Button.Click" Sourcename="button">
	<BeginStoryboard Storyboard="{staticResource sbkey}" />
</EventTrigger>

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

<Window.Resources>
	<PathGeometry Figures="M0,0 100,100 500,100 600,200" x:Key="path"/>
	<Storyboard x:Key="sb">
		<PointAnimationusingPath Storyboard.TargetName="eg" Duration="0:0:5" Storyboard.TargetProperty="Center"/>
	</Storyboard>
</Window.Resources>
<Window.Triggers>
	<EventTrigger RouteEvent="Window.Loaded">
		<BeginStroyboard Storyboard="{StaticResource sb}">
	</EventTrigger>
</Window.Triggers>
<Grid>
	<Path Data="{StaticResource path}" Stroke="Red" StrokeThickness="1"/>
	<Path Fill="Orange">
		<Path.Data>
			<EllipseGeometry Center="0,0" RadiusX="60" RadiusY="30" x:Name="eg"/>
		</Path.Data>
	</Path>
</Grid>
2.10. 事件触发器

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

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

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

<Application.Resources>
	<ResourceDictionary>            
		<SolidColorBrush x:Key="DefultWindowBG" Color="#FF1991EC"/>
	</ResourceDictionary>	
</Application.Resources>

 <Label 
  Content="{DynamicResource UserLabel}"  
  Foreground="{DynamicResource DefultWindowBG}" >
 <Label/>

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

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <!--  设置触发器  -->
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=RunStatus}" Value="False">
                <Setter Property="Background" Value="Gray" />
            </DataTrigger>

            <!--<Trigger Property="IsSelected" Value="true">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
            </Trigger>-->
        </Style.Triggers>
    </Style>
</ListView.ItemContainerStyle>
2.16. ListView根据显示内容更改ContextMenu MenuItem
<ListView
	Name="listView1"
	ItemsSource="{Binding FlowViewDataList}">
	<ListView.Resources>
		<Style x:Key="CheckMenuItem" TargetType="{x:Type MenuItem}">
			<Style.Triggers>
				<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem.RunStatus}" Value="True">
					<Setter Property="Header" Value="禁用" />
				</DataTrigger>
				<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem.RunStatus}" Value="False">
					<Setter Property="Header" Value="启用" />
				</DataTrigger>
			</Style.Triggers>
		</Style>

	</ListView.Resources>
	
	<ListView.ContextMenu>
		<ContextMenu Background="{DynamicResource DefultWindowBG}">
			<MenuItem
				Icon="{materialDesign:PackIcon Kind=Cancel}"
				Style="{StaticResource CheckMenuItem}">
			</MenuItem>
		</ContextMenu>
	</ListView.ContextMenu>
</ListView>
2.20. GridView的列宽度设置为按比例分配
<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0" x:Name="col1"/>
        <Grid Grid.Column="1" x:Name="col2"/>
        <Grid Grid.Column="2" x:Name="col3"/>
        <Grid Grid.Column="3" x:Name="col4"/>
    </Grid>
    <ListView x:Name="listview">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="header1" Width="{Binding ElementName=col1,Path=ActualWidth}"/>
                <GridViewColumn Header="header2" Width="{Binding ElementName=col2,Path=ActualWidth}"/>
                <GridViewColumn Header="header3" Width="{Binding ElementName=col3,Path=ActualWidth}"/>
                <GridViewColumn Header="header4" Width="{Binding ElementName=col4,Path=ActualWidth}"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
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. TreeView

https://www.cnblogs.com/cplemom/p/12078859.html

2.32. Style BaseOn

如果想在别的样式基础上,进行修改,用BasedOn

<TreeView.ItemContainerStyle>
                    <Style BasedOn="{StaticResource MaterialDesignTreeViewItem}" TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True" />
                    </Style>
                </TreeView.ItemContainerStyle>
2.33. InvokeCommandAction.CommandParameter传递多个参数

https://www.jianshu.com/p/873789538140
cs

/// <summary>
/// 用于从Xml中AddCoilCommand事件命令传递多参数转换
/// </summary>
class MultiValueConverter : IMultiValueConverter
{
	public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
	{
		List<object> list = new List<object>();
		foreach (object value in values)
		{ if (value == null) return null;
			list.Add(value);
		}

		return list;
	}

	public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

xaml

<UserControl.Resources>
	<ResourceDictionary>
		<ResourceDictionary.MergedDictionaries>
			<ResourceDictionary>
				<common:MultiValueConverter x:Key="multiValueConverter" />
			</ResourceDictionary>
	   </ResourceDictionary.MergedDictionaries>
	</ResourceDictionary>
</UserControl.Resources>

<i:Interaction.Triggers>
	<i:EventTrigger EventName="MouseDoubleClick">
        <i:InvokeCommandAction Command="{Binding DGMouseDoubleClickCommand}">
			<i:InvokeCommandAction.CommandParameter>
				<MultiBinding Converter="{StaticResource ResourceKey=multiValueConverter}">
					<Binding ElementName="DG_TestBoard" Path="SelectedItem" />
					<Binding ElementName="DG_TestBoard" Path="CurrentColumn" />
					<Binding ElementName="DG_TestBoard" Path="SelectedIndex" />
				</MultiBinding>
			</i:InvokeCommandAction.CommandParameter>
		</i:InvokeCommandAction>
	</i:EventTrigger>
</i:Interaction.Triggers>

3. 基础设置

<Windows
Title="系统登录" Height="600" Width="360"
FontFamily="Microsoft YaHei" FontWeight="ExtraLight"
ResizeMode="NoResize" 
WindowStartupLocation="CenterScreen"
WindowStyle="None" AllowsTransparency="True" 
Background="{x:Null}" >   无边框,无背景

**窗体四周小边框**
<Border Margin="5" Background="White" CornerRadius="10">
   <Border.Effect>
        <DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0" />
    </Border.Effect>
</Border>

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 表格按钮绑定事件
传的参数为当前行
<DataGridTemplateColumn Header="操作" MinWidth="120">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Content="{Binding OperationString}"
                            Command="{Binding DataContext.VideoOperationCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
                            CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

传的参数为整个datagrid
<Button Content="Set" Uid="{Binding Id}" HorizontalAlignment="Center" VerticalAlignment="Center"
	Style="{StaticResource SetButtonStyle}" Width="50" Background="#007DFA"
	Command="{Binding DataContext.SetClickCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
	CommandParameter="{Binding ElementName=pduData}" >
</Button>
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页面添加
<ResourceDictionary.MergedDictionaries>
<hc:ThemeResources />
<hc:Theme />
</ResourceDictionary.MergedDictionaries>

居中的样式

<Style
x:Key="DataGridTextCenterRowHeaserStyle"
 BasedOn="{StaticResource DataGridRowHeaderStyle}"
 TargetType="DataGridRowHeader">
 <Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style
 x:Key="DataGridTextCenterColumnStyle"
 BasedOn="{StaticResource DataGridCellStyle}"
 TargetType="DataGridCell">
 <Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style
 x:Key="DataGridTextCenterColumnHeaderStyle"
 BasedOn="{StaticResource DataGridColumnHeaderStyle}"
 TargetType="DataGridColumnHeader">
 <Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>


<DataGrid
x:Name="DataGridOneDC"
Width="390"
Height="300"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
hc:DataGridAttach.ShowRowNumber="True"
AutoGenerateColumns="False"
HeadersVisibility="All"
HorizontalScrollBarVisibility="Disabled"
IsReadOnly="True"
ItemsSource="{Binding OneDimensionalCodeDataCollection}"
RowHeaderStyle="{StaticResource DataGridTextCenterRowHeaserStyle}"
RowHeaderWidth="30">
<DataGrid.Columns>
    <DataGridTextColumn
        Width="17*"
        Binding="{Binding Content}"
        CellStyle="{StaticResource DataGridTextCenterColumnStyle}"
        Header="解码字符串"
        HeaderStyle="{StaticResource DataGridTextCenterColumnHeaderStyle}" />
</DataGrid.Columns>
</DataGrid>
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
<i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <mvvm:EventToCommand Command="{Binding LoadedHWCommand}" CommandParameter="{Binding ElementName=FormHost}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
viewmodel  
    public RelayCommand<object> LoadedHWCommand { get; set; }
    this.LoadedHWCommand = new RelayCommand<object>(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
<Button
   x:Name="Load_Pic"
   Width="90"
   Height="30"
   Margin="0,10"
   Command="{Binding LoadPicCommand}"
   CommandParameter="{Binding ElementName=hwindow}"
   Content="Load_Pic" />

viewmodel
public RelayCommand<object> LoadPicCommand { get; set; }
this.LoadPicCommand = new RelayCommand<object>(LoadPic);
//获取HWindowControlWPF控件对象
HWindow_Final hWindow_Fit1 = ((HWindow_Final)o);
3.11 pictureBox控件获取Resources的png
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Properties.Resources.查找);
IntPtr hBitmap = bmp.GetHbitmap();
System.Windows.Media.ImageSource WpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

this.pictureBox1.Source = WpfBitmap;
3.12 ComboBox 颜色选择器

https://blog.csdn.net/anjingyatou/article/details/18262639
通过SelectedIndex确定默认值

3.13 颜色字符串转16进制
System.Drawing.Color temp = System.Drawing.Color.FromName("red");
string temp = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(temp.R, temp.G, temp.B));
3.14 wpf使用iconfont

https://blog.csdn.net/wanxiweilai/article/details/126540296
如果在设计界面可以显示但是在运行界面不显示,需要修改ttf文件的属性,设置生成操作为资源

# xaml文件里的设置
FontFamily="../Fonts/#iconfont"
Text="&#xe665;"  
# 如果在代码里需要把 &# 改成 \
"\xe748"                 
3.15 引用外部程序集的资源

项目结构如下,主项目是AutoTestPlatform,AutoTest.Resource是专门放资源文件的程序集,主项目需要引用AutoTest.Resource里的资源。

1.  先把AutoTest.Resource添加到主项目中;
2.  FontFamily="/AutoTest.Resource;component/Fonts/#iconfont"
3.   <ResourceDictionary Source="/AutoTest.Resource;component/Styles/DefaultStyle.xaml"/>

在这里插入图片描述

3.16 遍历所有的空间
/// <summary>
/// 遍历所有的光开关通道
 /// </summary>
private void SearchAllCheckbox(FrameworkElement container)
        {
            foreach (var child in LogicalTreeHelper.GetChildren(container))
            {
                if (child is CheckBox)
                {
                    CheckBox cb = child as CheckBox;
                    if (cb.IsChecked == true)
                    {
                        checkboxList.Add(int.Parse(cb.Tag.ToString()));
                    }
                }
                FrameworkElement frameworkElement = child as FrameworkElement;
                if (frameworkElement != null)
                {
                    SearchAllCheckbox(frameworkElement);
                }
            }
        }
3.17 Datatrigger 判断不等于

https://www.cnblogs.com/DingGuo/p/14211553.html

<Style>
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <!--<Condition 1 here.../>-->
                    <!--<Condition 2 here.../>-->
                    <Condition>
                        <Condition.Binding>
                            <Binding Path="id" Converter="{StaticResource ValueToEqualsParameterConverter}">
                                <Binding.ConverterParameter> //没有定义全局Style
                                    <System:Int32>3</System:Int32> //没有定义全局Style
                                </Binding.ConverterParameter> //没有定义全局Style
                            </Binding>
                        </Condition.Binding>
                        <Condition.Value>
                            <System:Boolean>False</System:Boolean>
                        </Condition.Value>
                    </Condition>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="Black" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
                                
    //如果有定义全局Style,则注释上面三行,在全局Style中加入
     <local:ValueToEqualsParameterConverter x:Key = "ValueToEqualsParameterConverter"/>   

转换器

public class ValueToEqualsParameterConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 
        return value.ToString() == parameter.ToString(); 
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 
        return null; 
    }
}
3.17 DataGrid 根据 DataTrigger 显示多种行模板

https://zhuanlan.zhihu.com/p/538510004?utm_id=0

<DataGrid x:Name="MyDataGrid" ItemsSource="{Binding DataGridList}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
        
        <DataGridTemplateColumn Header="Type">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ContentControl>
                        <ContentControl.Style>
                            <Style TargetType="ContentControl">
                                <Style.Triggers>
                                    <!-- 当 Binding 的内容为 Value 时会触发 -->
                                    <DataTrigger Binding="{Binding Name}" Value="TextBox">
                                        <Setter Property="ContentTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <TextBox Text="This is a TextBox"/>
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Name}" Value="ComboBox">
                                        <Setter Property="Foreground" Value="Red"/>
                                        <Setter Property="ContentTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <ComboBox Text="This is a ComboBox" IsEditable="True">
                                                        <ComboBoxItem Content="Item 1"/>
                                                        <ComboBoxItem Content="Item 2"/>
                                                    </ComboBox>
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Name}" Value="TextBoxBinding">
                                        <Setter Property="ContentTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <TextBox Text="{Binding Content}"/>
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
                    </ContentControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

4. 语法

4.1. 绑定的几种方法
ElementnName     依据Name相互绑定
      Content="{Binding ElementName=txt1, path=Text}"
RelativeSource    相对于本身属性或者父元素属性
      Content="{RelativeSource Mode=Self}, Path=Height"
ItemSource    绑定到集合元素
      ItemSource="{Binding Collection}"
DataContext    多种不同值绑定
4.2. Show 和 ShowDialog 的区别

ShowDialog会卡住线程

4.3. 依赖属性

VS创建依赖属性快捷键 propdp
//依赖属性必须为static readonly
//DependencyProperty.Register 参数说明
//第一个参数是string类型的,是属性名。
//第二个参数是这个依赖项属性的类型。
//第三个参数是这个拥有这个依赖项属性的类型。
//第四个参数是具有附加属性设置的PropertyMetadata对象。

PropertyMetadata,FrameworkPropertyMetadata,UIPropertyMetadata
https://blog.csdn.net/Libby1984/article/details/53556721
只想通过dp支持属性并提供默认值,请使用PropertyMetadata
要指定动画行为,请使用UIPropertyMetadata
某些属性影响wpf框架级别的东西,例如元素布局,父布局或数据绑定,请使用FrameworkPropertyMetadata

4.4. Usercontrol Customtrol

https://www.bilibili.com/video/BV1q64y1U7Zk?p=12

Usercontrol 用户控件,继承与系统的控件, 控件的组装,只能使用系统自带控件的属性,
Customtrol 自定义控件,真正的控件,自定义控件属性,控件样式
xaml文件一定要放在Themes文件夹下,可以有一下这些名字,根据系统样式选择对应的xaml文件
在这里插入图片描述

4.5. ObservableCollection

ObservableCollection 跟 List一样使用
ObservableCollection 对象的增减可以通知界面的更新,对象内容的改变不会通知界面的更新
public ObservableCollection Collection = new ObservableCollection();

List<T>和ObservableCollection<T>的相互转换

1.ObservableCollection转换List
ObservableCollection o; // 假设已经赋值
List list = new List(o.ToList());
2.List转换ObservableCollection
List list; // 假设已经赋值
// 方法1
ObservableCollection o = new ObservableCollection(list);
//方法2
ObservableCollection o = new ObservableCollection();
list.Foreach(l => o.Add(l));

4.6. 十六进制转Brush
(SolidColorBrush)(new BrushConverter().ConvertFrom("#ffaacc"));
4.7. 跨线程更新UI
 System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
{
    ...........
}));
4.8. 通过Bing修改依赖属性 和 直接访问控件属性的冲突

修改一个按钮的状态

①直接通过this.but_openSerial.IsEnabled = false 修改
②通过OpenSerialEnabled = true修改
通过①修改之后,再通过②修改,不生效,不能同时采用两种方式修改
可以通过 MVVMLight学习笔记(七)—Messenger使用 都使用第二种方式修改

5. 第三方库

5.1. MaterialDesignThemes

①使用 NuGet 安裝
②修改 App.xaml

<Application.Resources>
`	<ResourceDictionary>
    	<ResourceDictionary.MergedDictionaries>
	        <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
	        <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
	        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
	        <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
	    </ResourceDictionary.MergedDictionaries>
	</ResourceDictionary>`
</Application.Resources>

③修改 MainWindow.xaml
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

使用Material Design的 Picker
需要把toolkit里复制的code放到 <materialDesign:DialogHost />里面
相对应的ViewModel里添加绑定的数据
添加CombinedDialogOpenedEventHandler等函数

版本4.9.0 Snackbar 不能修改FontSize的问题,可以参考https://github.com/MichelMichels/MaterialDesignInXamlToolkit/commit/90cf05241333229fa74d4b4894c25b7b978f2669
拉取4.9.0的库,更新MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Snackbar.xaml,重新生成dll即可``

<md:Snackbar x:Name="LoginSnakeBar" Grid.Row="3" Grid.ColumnSpan="2" Foreground="White" 
                        Background="#673ab7" MessageQueue="{md:MessageQueue}" FontSize="13">
</md:Snackbar>           
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters"
                    xmlns:system="clr-namespace:System;assembly=mscorlib"
                    xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf">

  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
  </ResourceDictionary.MergedDictionaries>

  <converters:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
  <converters:MathMultipleConverter x:Key="MathMultipleConverter"
                                    Operation="Multiply" />
  <converters:SnackbarActionButtonPlacementModeConverter x:Key="SnackbarActionButtonPlacementModeConverter" />

  <Style x:Key="MaterialDesignSnackbarActionButton"
         TargetType="Button">
    <Setter Property="Background"
            Value="Transparent" />
    <Setter Property="BorderBrush"
            Value="Transparent" />
    <Setter Property="BorderThickness"
            Value="1" />
    <Setter Property="Cursor"
            Value="Hand" />
    <Setter Property="FocusVisualStyle"
            Value="{StaticResource FocusVisual}" />
    <Setter Property="Foreground"
            Value="{DynamicResource SecondaryHueMidBrush}" />
    <Setter Property="Height"
            Value="36" />
    <Setter Property="HorizontalContentAlignment"
            Value="Center" />
    <Setter Property="Margin"
            Value="8,-10,-8,-10" />
    <Setter Property="Padding"
            Value="8" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
          <Grid x:Name="Root"
                Background="{TemplateBinding Background}">
            <wpf:Ripple Padding="{TemplateBinding Padding}"
                        HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                        Content="{TemplateBinding Content}"
                        ContentTemplate="{TemplateBinding ContentTemplate}"
                        Focusable="False"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
          </Grid>
          <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver"
                     Value="true">
              <Setter Property="Background"
                      Value="{DynamicResource MaterialDesignSnackbarMouseOver}" />
            </Trigger>
            <Trigger Property="IsEnabled"
                     Value="false">
              <Setter Property="Opacity"
                      Value="0.38" />
            </Trigger>
            <Trigger Property="DockPanel.Dock"
                     Value="Bottom">
              <Setter Property="Margin"
                      Value="0,18,-8,-8" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="TextBlock.FontSize"
            Value="14" />
    <Setter Property="TextBlock.FontWeight"
            Value="Medium" />
    <Setter Property="VerticalAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Center" />
    <Setter Property="wpf:RippleAssist.Feedback"
            Value="{DynamicResource MaterialDesignSnackbarRipple}" />
  </Style>

  <Style x:Key="MaterialDesignSnackbarActionLightButton"
         TargetType="Button"
         BasedOn="{StaticResource MaterialDesignSnackbarActionButton}">
    <Setter Property="Foreground"
            Value="{DynamicResource PrimaryHueLightBrush}" />
  </Style>

  <Style x:Key="MaterialDesignSnackbarActionMidButton"
         TargetType="Button"
         BasedOn="{StaticResource MaterialDesignSnackbarActionButton}">
    <Setter Property="Foreground"
            Value="{DynamicResource PrimaryHueMidBrush}" />
  </Style>

  <Style x:Key="MaterialDesignSnackbarActionDarkButton"
         TargetType="Button"
         BasedOn="{StaticResource MaterialDesignSnackbarActionButton}">
    <Setter Property="Foreground"
            Value="{DynamicResource PrimaryHueDarkBrush}" />
  </Style>

  <Style TargetType="wpf:SnackbarMessage">
    <Setter Property="HorizontalContentAlignment"
            Value="Left" />
    <Setter Property="Margin"
            Value="16" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="wpf:SnackbarMessage">
          <DockPanel>
            <!-- will become a Panel to wrap a "pretend" button -->
            <Button x:Name="PART_ActionButton"
                    HorizontalAlignment="Right"
                    Panel.ZIndex="1"
                    Command="{TemplateBinding ActionCommand}"
                    CommandParameter="{TemplateBinding ActionCommandParameter}"
                    Content="{TemplateBinding ActionContent}"
                    ContentStringFormat="{TemplateBinding ActionContentStringFormat}"
                    ContentTemplate="{TemplateBinding ActionContentTemplate}"
                    ContentTemplateSelector="{TemplateBinding ActionContentTemplateSelector}"
                    Style="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type wpf:Snackbar}}, Path=ActionButtonStyle}"
                    Visibility="{TemplateBinding ActionContent, Converter={StaticResource NullableToVisibilityConverter}}">
              <DockPanel.Dock>
                <MultiBinding Converter="{StaticResource SnackbarActionButtonPlacementModeConverter}">
                  <Binding Path="ActionButtonPlacement"
                           RelativeSource="{RelativeSource AncestorType={x:Type wpf:Snackbar}}" />
                  <Binding Path="(wpf:SnackbarMessage.InlineActionButtonMaxHeight)"
                           RelativeSource="{RelativeSource AncestorType={x:Type wpf:Snackbar}}" />
                  <Binding Path="ActualHeight"
                           RelativeSource="{RelativeSource AncestorType={x:Type wpf:Snackbar}}" />
                </MultiBinding>
              </DockPanel.Dock>
            </Button>

            <ContentPresenter MaxHeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:Snackbar}}, Path=(wpf:SnackbarMessage.ContentMaxHeight)}"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              Content="{TemplateBinding Content}"
                              ContentStringFormat="{TemplateBinding ContentStringFormat}"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}">
              <ContentPresenter.Resources>
                <DataTemplate DataType="{x:Type system:String}">
                  <TextBlock Padding="0"
                             Text="{Binding}">
                    <TextBlock.Style>
                      <Style TargetType="{x:Type TextBlock}"
                             BasedOn="{StaticResource MaterialDesignBody1TextBlock}">
                        <Setter Property="TextTrimming"
                                Value="CharacterEllipsis" />
                        <Setter Property="TextWrapping"
                                Value="WrapWithOverflow" />
                        <Setter Property="FontSize"
                                Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:Snackbar}}, Path=FontSize}" />
                        <Setter Property="FontWeight"
                                Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:Snackbar}}, Path=FontWeight}" />
                      </Style>
                    </TextBlock.Style>
                  </TextBlock>
                </DataTemplate>
              </ContentPresenter.Resources>
            </ContentPresenter>
          </DockPanel>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

  <Style TargetType="wpf:Snackbar">
    <Setter Property="ActionButtonStyle"
            Value="{StaticResource MaterialDesignSnackbarActionButton}" />
    <Setter Property="Background"
            Value="{DynamicResource MaterialDesignSnackbarBackground}" />
    <Setter Property="ClipToBounds"
            Value="True" />
    <Setter Property="FontSize"
            Value="14" />
    <Setter Property="Foreground"
            Value="{DynamicResource MaterialDesignPaper}" />
    <Setter Property="HorizontalAlignment"
            Value="Center" />
    <Setter Property="MaxWidth"
            Value="568" />
    <Setter Property="MinWidth"
            Value="288" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="wpf:Snackbar">
          <ControlTemplate.Resources>
            <Storyboard x:Key="ActivateStoryboard"
                        Duration="0:0:0.3">
              <DoubleAnimation Storyboard.TargetName="Root"
                               Storyboard.TargetProperty="Tag"
                               From="0"
                               To="1"
                               Duration="0:0:0.3">
                <DoubleAnimation.EasingFunction>
                  <SineEase EasingMode="EaseOut" />
                </DoubleAnimation.EasingFunction>
              </DoubleAnimation>
              <DoubleAnimation BeginTime="0"
                               Storyboard.TargetName="ContentPresenter"
                               Storyboard.TargetProperty="Opacity"
                               To="0"
                               Duration="0" />
              <DoubleAnimation BeginTime="0:0:0.075"
                               Storyboard.TargetName="ContentPresenter"
                               Storyboard.TargetProperty="Opacity"
                               From="0"
                               To="1"
                               Duration="0:0:0.225">
                <DoubleAnimation.EasingFunction>
                  <SineEase EasingMode="EaseOut" />
                </DoubleAnimation.EasingFunction>
              </DoubleAnimation>
            </Storyboard>
            <Storyboard x:Key="DeactivateStoryboard"
                        Duration="0:0:0.3">
              <DoubleAnimation Storyboard.TargetName="Root"
                               Storyboard.TargetProperty="Tag"
                               From="1"
                               To="0"
                               Duration="0:0:0.3">
                <DoubleAnimation.EasingFunction>
                  <SineEase EasingMode="EaseOut" />
                </DoubleAnimation.EasingFunction>
              </DoubleAnimation>
            </Storyboard>
          </ControlTemplate.Resources>
          <StackPanel x:Name="Root">
            <StackPanel.Tag>
              <system:Double>0.0</system:Double>
            </StackPanel.Tag>
            <StackPanel.Height>
              <MultiBinding Converter="{StaticResource MathMultipleConverter}">
                <Binding ElementName="ContentBorder"
                         Path="ActualHeight" />
                <Binding Path="Tag"
                         RelativeSource="{RelativeSource Self}" />
              </MultiBinding>
            </StackPanel.Height>
            <Border x:Name="ContentBorder"
                    MinHeight="48"
                    VerticalAlignment="Stretch"
                    Background="{TemplateBinding Background}"
                    CornerRadius="3"
                    SnapsToDevicePixels="True">
              <ContentPresenter x:Name="ContentPresenter"
                                Margin="{TemplateBinding Padding}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding Message}" />
            </Border>
          </StackPanel>
          <ControlTemplate.Triggers>
            <Trigger Property="IsActive"
                     Value="True">
              <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource ActivateStoryboard}" />
              </Trigger.EnterActions>
              <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource DeactivateStoryboard}" />
              </Trigger.ExitActions>
            </Trigger>
            <Trigger Property="HorizontalAlignment"
                     Value="Stretch">
              <Setter TargetName="ContentBorder"
                      Property="CornerRadius"
                      Value="0" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="VerticalAlignment"
            Value="Bottom" />
    <Setter Property="VerticalContentAlignment"
            Value="Center" />
    <Style.Triggers>
      <Trigger Property="HorizontalAlignment"
               Value="Stretch">
        <Setter Property="MaxWidth"
                Value="{x:Static system:Double.MaxValue}" />
      </Trigger>
    </Style.Triggers>
  </Style>

</ResourceDictionary>

              
5.2. HeBianGu

https://blog.csdn.net/u010975589/article/details/103083605

添加HeBianGu.Base.WpfBase.dll 和 HeBianGu.General.WpfControlLib.dll 两个dll文件(下载地址),在App.xml文件里添加下面内容

<ResourceDictionary.MergedDictionaries>
                <!--  用于设置动态主题  -->
                <ResourceDictionary Source="/HeBianGu.Base.WpfBase;component/Theme/Color/LightThemeResource.xaml" />
                <!--  用于设置基础资源  -->
                <ResourceDictionary Source="/HeBianGu.Base.WpfBase;component/Theme/HeBianGu.Theme.Default.xaml" />
                <!--  用于设置控件样式  -->
                <ResourceDictionary Source="/HeBianGu.General.WpfControlLib;component/Theme/HeBianGu.Themes.Default.xaml" />
</ResourceDictionary.MergedDictionaries>

在xaml文件中添加引用 xmlns:h=“leoh”
打开HeBianGu-master\Product\Debug文件夹下的HeBianGu.Application.BlurWindow.exe,从里面找到你需要的控件,从HeBianGu-master\Source\Application\HeBianGu.Application.BlurWindow\TreeDictionary.xaml里面找到控件所在的xaml,模仿写法

ComboBox
<ComboBox HorizontalAlignment="Center" Width="190" Height="30" RenderTransform="{DynamicResource S.TransformGroup.Default}"
                                  h:Cattach.Label="串    口   " ItemsSource="{Binding CollectionSerial}"
                                  Style="{DynamicResource S.ComboBox.LabelClear}" h:Cattach.Watermark="请选择串口" />
皮肤主题
<h:ThemeSetControl Foreground="{DynamicResource S.Brush.TextForeground.White}" />

图片的放大功能
①使用 NuGet 安裝, HeBianGu.General.ImageCore
②xmlns:imagecore=“clr-namespace:HeBianGu.General.ImageCore;assembly=HeBianGu.General.ImageCore”
③代码

<TabControl>
        <TabItem Header="鼠标滚轮放大">
            <Grid>
                <imageview:ImageCore ImageSource="{StaticResource S.ImageSource.Default}" OperateType="Default"/>

            </Grid>
        </TabItem>

        <TabItem Header="标记矩形范围放大">
            <Grid>
                <imageview:ImageCore ImageSource="{StaticResource S.ImageSource.Default}" OperateType="Enlarge"/>
            </Grid>
        </TabItem>

        <TabItem Header="标记矩形">
            <Grid>
                <imageview:ImageCore ImageSource="{StaticResource S.ImageSource.Default}" OperateType="Sign"/>
            </Grid>
        </TabItem>

        <TabItem Header="放大镜">
            <Grid>
                <imageview:ImageCore ImageSource="{StaticResource S.ImageSource.Default}" OperateType="Bubble"/>
            </Grid>
        </TabItem>
    </TabControl>
5.3 LiveCharts

①使用 NuGet 安裝
②xmlns:lvc=“clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf”

5.4 XAML 格式化工具:XAML Styler

https://blog.csdn.net/u014453443/article/details/113754047

6. 把dll 文件放到单个的文件夹中

https://www.bilibili.com/video/BV1UE411R7g2?p=10
App.config

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>
5.4 MVVMLight

关于Messager的使用
①MessageBase类型
Messenger.Default.Register(this, “MSerialInfo”, ReceiveSerialInfo);
Messenger.Default.Send(receiveStr, “SerialInfo”);
自定义类型
Messenger.Default.Register<bool[]>(this, “State”, func);
bool[] arr = { false, true};
Messenger.Default.Send(arr, “State”);
②GenericMessage类型
Messenger.Default.Register<GenericMessage<bool[]>>(this, “State”, func);
bool[] arr = { false, true};
Messenger.Default.Send<GenericMessage<bool[]>>(new GenericMessage<bool[]>(arr), “State”);

  1. https://www.cnblogs.com/xiaoke-/p/16730318.html
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

huangle63

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

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

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

打赏作者

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

抵扣说明:

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

余额充值