WPF学习笔记
Style
BaseOn
继承基础属性集合
Setter
属性集合,可以减少相同属性控件的代码量
Trigger
属性触发器,可以为控件做简单的动画效果。
控件模板
ControlTemplate --> 显示内容,背景颜色,对齐
<Window.Resources>
<Style x:Key="Mybtn" TargetType="Button">
<Setter Property="Background" Value="Aqua"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<!--控件大小尺寸-->
<Grid Background="{TemplateBinding Background}">
<Border x:Name="HearderBorder"/>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HearderBorder" Property="BorderThickness" Value="2 0 0 0"/>
<Setter TargetName="HearderBorder" Property="BorderBrush" Value=" BlueViolet"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid>
<Button Width="120" Height="30" Style="{StaticResource Mybtn}" Content="123" Background="Red" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Grid>
数据模板
以自定义的控件排布在空间上显示数据
<ListBox x:Name="list" BorderThickness="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Icon}"/>
<TextBlock Text="{Binding Title}" Margin="5 0 0 0"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Binding
控件间的绑定
默认是双向绑定的(OneWay,OneTime,OneWayToSource,TwoWay);
<Slider x:Name="sl1" Minimum="0" Maximum="100"/>
<TextBox x:Name="txt1" Text="{Binding ElementName=sl1,Path=Value}"/>
<Slider x:Name="sl2" Minimum="{Binding ElementName=sl1,Path=Minimum}" Maximum="{Binding ElementName=sl1,Path=Maximum}" Value="{Binding ElementName=sl1,Path=Value}"/>
命令
添加一个类,继承ICommand接口
public class MyCommand : ICommand
{
Action excuteAction;
public MyCommand(Action action)
{
excuteAction = action;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
excuteAction();
}
}
在ViewModel中应用
public partial class Test
{
public MyCommand ShowCommand { get; set; }
public Test()
{
ShowCommand = new MyCommand(Show);
}
public void Show()
{
MessageBox.Show("点击了按钮");
}
behavior 行为
<ListBox x:Name="listMenu"
ItemsSource="{Binding MenuBars}"
SelectedIndex="0">
<i:Interaction.Triggers>
<!--给ListBox添加一个选项改变行为命令-->
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding OpenNevegate}"
CommandParameter="{Binding ElementName=listMenu,Path=SelectedItem}"/>
</i:EventTrigger>
<!--给App添加一个加载初始导航画面行为命令-->
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding OpenNevegate}"
CommandParameter="{Binding ElementName=listMenu,Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
属性更改通知
新增一个类继承INotifyPropertyChanged
基础版
public class Test : INotifyPropertyChanged
{
private string _title;
public string Title
{
get { return _title; }
set { _title = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Title"));
}
}
public event PropertyChangedEventHandler? PropertyChanged;
}
稍微进步点版 [CallerMemberName]添加一个特性,可以不用写一串
public class BindBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
转换器 IValueConverter
添加一个类IDisPlay继承IValueConverter
IDisPlay.cs代码
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace PrismMy
{
public class IDisPlay : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
var str = value.ToString();
if(str == "0")
return "Yes";
else if(str == "1")
return "No";
}
return "未知";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
MainWindow.xaml代码
<Window.Resources>
<local:IDisPlay x:Key="ValueConvert"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackPanel>
<TextBlock x:Name="tx1" Text="0" FontSize="50" />
<TextBlock x:Name="tx2" Text="1" FontSize="50" />
<TextBlock x:Name="tx3" Text="2" FontSize="50" />
<TextBlock Text="{Binding Path=Text,ElementName=tx1,Converter={StaticResource ValueConvert}}" FontSize="50"/>
<TextBlock Text="{Binding Path=Text,ElementName=tx2,Converter={StaticResource ValueConvert}}" FontSize="50"/>
<TextBlock Text="{Binding Path=Text,ElementName=tx3,Converter={StaticResource ValueConvert}}" FontSize="50"/>
</StackPanel>
</Grid>
多值转换器 IMultiValueConverter
新增一个类IDisMultiPlay.cs继承IMultiValueConverter接口
IDisMultiPlay.cs代码
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;
namespace PrismMy
{
public class IDisMultiPlay : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length < 3)
return null;
byte R = System.Convert.ToByte(values[0]);
byte G = System.Convert.ToByte(values[1]);
byte B = System.Convert.ToByte(values[2]);
Color color = Color.FromRgb(R, G, B);
SolidColorBrush brush = new SolidColorBrush(color);
return brush;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
MainWindow.xaml代码
<StackPanel Grid.Column="1">
<Slider x:Name="sl1" Minimum="0" Maximum="255" Width="200" Height="20"/>
<Slider x:Name="sl2" Minimum="0" Maximum="255" Width="200" Height="20"/>
<Slider x:Name="sl3" Minimum="0" Maximum="255" Width="200" Height="20"/>
<Path HorizontalAlignment="Center">
<Path.Data>
<EllipseGeometry Center="100 100" RadiusX="50" RadiusY="50"/>
</Path.Data>
<Path.Fill>
<MultiBinding Converter="{StaticResource MultiConvert}">
<Binding ElementName="sl1" Path="Value"/>
<Binding ElementName="sl2" Path="Value"/>
<Binding ElementName="sl3" Path="Value"/>
</MultiBinding>
</Path.Fill>
</Path>
</StackPanel>