21-StaticResource的使用
StaticResource也是个扩展标记,而它呢就起到一个引入的作用,引入数据字典中定义的一个静态资源
比如下面
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="myButton" TargetType="Button">
<Setter Property="Width" Value="200"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="Background" Value="Orange"/>
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Button Style="{StaticResource myButton}">点击</Button>
<Button>点击2</Button>
<Button Style="{StaticResource myButton}">点击3</Button>
<Button>点击3</Button>
</StackPanel>
</Window>Code language: HTML, XML (xml)
22-文字颜色渐变效果
<Style x:Key="textBlockStyle" TargetType="TextBlock">
<!--字体渐变-->
<Setter Property="Foreground">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Red" Offset="0.0" />
<GradientStop Color="Blue" Offset="0.5" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="200"/>
<Setter Property="Opacity" Value="0.02"/>
</Style>Code language: HTML, XML (xml)
增加一个样式
在相应的地方 使用
<TextBlock Style="{StaticResource textBlockStyle}">Code language: HTML, XML (xml)
23-使用Canvas模拟实现进度条
由于windows7下面的进度条感觉不好看 没有扁平化效果 所以使用Canvas来实现
<Canvas Grid.Row="0" Grid.Column="0" Background="White" Height="{Binding Index[0].Height}" VerticalAlignment="Bottom"/>
<Canvas Grid.Row="0" Grid.Column="0" Background="{Binding Index[0].Color}" VerticalAlignment="Bottom">
<Canvas.Height>
<MultiBinding Converter="{StaticResource cvtDate}">
<Binding Path="Index[0].Max"/>
<Binding Path="Index[0].Count"/>
<Binding Path="Index[0].Height"/>
</MultiBinding>
</Canvas.Height>
</Canvas>Code language: HTML, XML (xml)
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
BorderBrush="Transparent"
BorderThickness="0"
d:DesignHeight="450" d:DesignWidth="800" MinWidth="45" Margin="2.5,0,2.5,0">
<UserControl.Resources>
<Style TargetType="ProgressBar">
<Setter Property="Background" Value="#ccc"></Setter>
<Setter Property="Foreground" Value="#638A2D"></Setter>
<Setter Property="FontSize" Value="12"></Setter>
</Style>
<local:MathConverter x:Key="cvtDate"/>Code language: JavaScript (javascript)
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 WpfApp2
{
public class MathConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double max = System.Convert.ToDouble(values[0]);
double count = System.Convert.ToDouble(values[1]);
double height = System.Convert.ToDouble(values[2]);
return height*count/max;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
下面是我们的例子
<Window x:Class="PrograssDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PrograssDemo"
mc:Ignorable="d"
Background="Blue"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MathConverter x:Key="cvtDate"/>
</Window.Resources>
<StackPanel>
<ProgressBar Maximum="{Binding Max}" Minimum="0" Value="{Binding Value}" Height="20" Width="{Binding Width}" Margin="50" HorizontalAlignment="Left"></ProgressBar>
<Grid>
<Canvas Width="{Binding Width}" Height="20" Background="White" Margin="50" HorizontalAlignment="Left"></Canvas>
<Canvas Height="20" Background="Green" Margin="50" HorizontalAlignment="Left">
<Canvas.Width>
<MultiBinding Converter="{StaticResource cvtDate}">
<Binding Path="Max"/>
<Binding Path="Value"/>
<Binding Path="Width"/>
</MultiBinding>
</Canvas.Width>
</Canvas>
</Grid>
</StackPanel>
</Window>Code language: HTML, XML (xml)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace PrograssDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private ProgressViewModel progressViewModel = new ProgressViewModel() { Value = 20,Max = 100,Width = 500 };
public MainWindow()
{
InitializeComponent();
this.DataContext = progressViewModel;
new Thread(new ThreadStart(Deal)) { IsBackground = true }.Start();
}
private void Deal()
{
while (true)
{
progressViewModel.Value++;
if(progressViewModel.Value > progressViewModel.Max)
{
progressViewModel.Value = 0;
}
Thread.Sleep(200);
}
}
}
}Code language: HTML, XML (xml)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace PrograssDemo
{
public class MathConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double max = System.Convert.ToDouble(values[0]);
double value = System.Convert.ToDouble(values[1]);
double width = System.Convert.ToDouble(values[2]);
return width * value / max;//500 * 5 / 100
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PrograssDemo
{
public class ProgressViewModel: INotifyPropertyChanged
{
private int _value;
public int Value
{
get
{
return _value;
}
set
{
_value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
}
}
private int _width;
public int Width
{
get
{
return _width;
}
set
{
_width = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Width"));
}
}
private int _max;
public int Max
{
get
{
return _max;
}
set
{
_max = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Max"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}Code language: PHP (php)
24-IMultiValueConverter
可以在XAML中传入多个绑定的值。然后在后台代码中(实现了IMultiValueConverter的转换器),然后进行转换
25-IValueConverter
它和IMultiValueConverter一样的作用 区别就是IMultiValueConverter 这个是可以传入多个绑定的值 而IValueConverter 就只能一个
private int _week;
public int Week
{
get
{
return _week;
}
set
{
_week = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Week"));
}
}Code language: JavaScript (javascript)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace PrograssDemo
{
public class WeekConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int week = System.Convert.ToInt32(value);
switch (week)
{
case 0:return "星期天";
case 1:return "星期一";
case 2:return "星期2";
case 3:return "星期3";
case 4:return "星期si";
case 5:return "星期五";
case 6:return "星期六";
default: return "不值钱";
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
<Window x:Class="PrograssDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PrograssDemo"
mc:Ignorable="d"
Background="Blue"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MathConverter x:Key="cvtDate"/>
<local:WeekConverter x:Key="weekConvert"/>
</Window.Resources>
<StackPanel>
<ProgressBar Maximum="{Binding Max}" Minimum="0" Value="{Binding Value}" Height="20" Width="{Binding Width}" Margin="50" HorizontalAlignment="Left"></ProgressBar>
<Grid>
<Canvas Width="{Binding Width}" Height="20" Background="White" Margin="50" HorizontalAlignment="Left"></Canvas>
<Canvas Height="20" Background="Green" Margin="50" HorizontalAlignment="Left">
<Canvas.Width>
<MultiBinding Converter="{StaticResource cvtDate}">
<Binding Path="Max"/>
<Binding Path="Value"/>
<Binding Path="Width"/>
</MultiBinding>
</Canvas.Width>
</Canvas>
</Grid>
<TextBlock Text="{Binding Week,Converter={StaticResource weekConvert},ConverterParameter='星期几'}"></TextBlock>
</StackPanel>
</Window>Code language: HTML, XML (xml)
26-右键菜单ContextMenu
WPF中的右键菜单主要是通过ContextMenu来实现,ContextMenu的使用有两种方式
一、在Resources中声明,在控件中使用。
1.在Resources中添加ContextMenu
<Window.Resources>
<ContextMenu x:Key="ContextMenu">
<MenuItem Name="MiFullScreen" Header="全屏"/>
<Separator></Separator>
<MenuItem Name="MiPlay" Header="播放"/>
</ContextMenu>
</Window.Resources>Code language: HTML, XML (xml)
2.在控件中使用ContextMenu
直接在控件的ContextMenu属性中关联即可。
<GroupBox ContextMenu="{StaticResource ContextMenu}">
</GroupBox>Code language: HTML, XML (xml)
3.为每个MenuItem写Click事件
此方法的优点在于只声明一次,可以在多个控件中同时使用
二、在控件中直接声明
<GroupBox >
<GroupBox.ContextMenu>
<ContextMenu>
<MenuItem Name="MenuItem1" Header="文件"/>
<MenuItem Name="MenuItem2" Header="编辑"/>
</ContextMenu>
</GroupBox.ContextMenu>
</GroupBox>Code language: HTML, XML (xml)
<Window x:Class="PrograssDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PrograssDemo"
mc:Ignorable="d"
Background="Blue"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MathConverter x:Key="cvtDate"/>
<local:WeekConverter x:Key="weekConvert"/>
<ContextMenu x:Key="ContextMenu">
<MenuItem Name="MiFullScreen" Header="全屏"/>
<Separator></Separator>
<MenuItem Name="MiPlay" Header="播放"/>
</ContextMenu>
</Window.Resources>
<StackPanel ContextMenu="{StaticResource ContextMenu}">
<ProgressBar Maximum="{Binding Max}" Minimum="0" Value="{Binding Value}" Height="20" Width="{Binding Width}" Margin="50" HorizontalAlignment="Left"></ProgressBar>
<Grid>
<Canvas Width="{Binding Width}" Height="20" Background="White" Margin="50" HorizontalAlignment="Left"></Canvas>
<Canvas Height="20" Background="Green" Margin="50" HorizontalAlignment="Left">
<Canvas.Width>
<MultiBinding Converter="{StaticResource cvtDate}">
<Binding Path="Max"/>
<Binding Path="Value"/>
<Binding Path="Width"/>
</MultiBinding>
</Canvas.Width>
</Canvas>
</Grid>
<TextBlock Text="{Binding Week,Converter={StaticResource weekConvert},ConverterParameter='星期几'}"></TextBlock>
</StackPanel>
</Window>Code language: HTML, XML (xml)
27-属性触发器-PropertyTrigger
触发器有三种类型:
- 属性触发器Property Trigger:当Dependency Property的值发生改变时触发。
- 数据触发器Data Trigger: 当普通.NET属性的值发生改变时触发。
- 事件触发器Event Trigger: 当路由时间被触发时调用。
触发器,从某种意义上来说它也是一种Style,因为它包含有一个Setter集合,并根据一个或多个条件执行Setter中的属性改变。属性触发器是在当某个依赖属性的值发生变化时触发执行一个Setter的集合,当属性失去这个值时,这些被触发执行的Setter集合会自动被撤销。
<Window x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="buttonMouseOver" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="10"></RotateTransform>
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
<Setter Property="Background" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel VerticalAlignment="Center">
<Button Width="200" Style="{StaticResource buttonMouseOver}">按钮</Button>
</StackPanel>
</Window>Code language: HTML, XML (xml)
此外 还可以用来进行验证。比如输入错误的时候 改变文本框的外观。
<Window x:Class="TriggerDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TriggerDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="myBtn" TargetType="Button">
<Setter Property="Width" Value="250"/>
<Setter Property="Height" Value="30"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Width" Value="250"/>
<Setter Property="Height" Value="60"/>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="90"></RotateTransform>
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Style="{StaticResource myBtn}">点我</Button>
</StackPanel>
</Window>Code language: HTML, XML (xml)
28-属性触发器应用-错误提示引用
我们可以在一些表单控件 比如textbox等 做一些验证 如果输入不对 则让文本框边框或者其他属性 做一些修改。这样子 达到提示效果。比如 我们要输入一个网址 我们可以添加一个网址的验证类 然后这个类去进行验证 判断用户填写的是不是网址。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp4
{
public class MyViewModel:INotifyPropertyChanged
{
private string _webSite;
public string WebSite
{
get
{
return _webSite;
}
set
{
_webSite = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("WebSite"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}Code language: PHP (php)
<Window x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="validateTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="30" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel VerticalAlignment="Center">
<TextBox Style="{StaticResource validateTextBoxStyle}">
<TextBox.Text>
<Binding UpdateSourceTrigger="PropertyChanged" Path="WebSite">
<Binding.ValidationRules>
<local:HttpValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Width="300" Height="30" Margin="5"></TextBox>
</StackPanel>
</Window>Code language: HTML, XML (xml)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace WpfApp4
{
public class HttpValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
string url = value.ToString();
if (!url.EndsWith("http://", StringComparison.InvariantCultureIgnoreCase))
{
return new ValidationResult(false,url+ "不是一个无效的网址");
}
else
{
return new ValidationResult(true, null);
}
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyViewModel();
}
}
29-验证提示自定义模板Validation.ErrorTemplate
验证提示的模板 为我们 可以自定义
<Window x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="validateTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="30" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel VerticalAlignment="Center">
<TextBox Style="{StaticResource validateTextBoxStyle}">
<TextBox.Text>
<Binding UpdateSourceTrigger="PropertyChanged" Path="WebSite">
<Binding.ValidationRules>
<local:HttpValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<Validation.ErrorTemplate>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<AdornedElementPlaceholder Name="customAdorner"></AdornedElementPlaceholder>
<TextBlock Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Margin="10,0,0,0" VerticalAlignment="Center" Foreground="Red" >
</TextBlock>
</StackPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
<TextBox Width="300" Height="30" Margin="5"></TextBox>
</StackPanel>
</Window>Code language: HTML, XML (xml)
30-错误提示增加红色图标
错误提示模板我们是可以随便定义的 里面可以使用布局控件 比如grid stackpanel等等。当然可以包含图片了。
<Validation.ErrorTemplate>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<AdornedElementPlaceholder Name="customAdorner"></AdornedElementPlaceholder>
<Image Source="E:\更多--FoxDevelop\WPF进阶\ErrorNotify\ErrorNotify\cross-circle.png"/>
<TextBlock Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Margin="10,0,0,0" VerticalAlignment="Center" Foreground="Red" >
</TextBlock>
</StackPanel>
</ControlTemplate>
</Validation.ErrorTemplate>Code language: HTML, XML (xml)