1 新建wpf项目
2 新建wpf UserControl类库
3 在类库中添加类,设置重写默认样式,添加部件和模板可视化状态声明
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace CustomControl
{
[TemplatePart(Name = "FlipButton", Type = typeof(ToggleButton)),
TemplateVisualState(Name = "Normal", GroupName = "ViewStates"),
TemplateVisualState(Name = "Flipped", GroupName = "ViewStates")]
public class FlipPanel:Control
{
static FlipPanel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FlipPanel), new FrameworkPropertyMetadata(typeof(FlipPanel))) ;
}
public object FrontContent
{
get { return (object)GetValue(FrontContentProperty); }
set { SetValue(FrontContentProperty, value); }
}
public object BackContent
{
get { return (object)GetValue(BackContentProperty); }
set { SetValue(BackContentProperty, value); }
}
public bool IsFlipped
{
get { return (bool)GetValue(IsFlippedProperty); }
set
{
SetValue(IsFlippedProperty, value);
ChangeVisualState(true);
}
}
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(FlipPanel), null);
public static readonly DependencyProperty IsFlippedProperty =
DependencyProperty.Register("IsFlipped", typeof(bool), typeof(FlipPanel), null);
public static readonly DependencyProperty FrontContentProperty =
DependencyProperty.Register("FrontContent", typeof(object), typeof(FlipPanel), null);
public static readonly DependencyProperty BackContentProperty =
DependencyProperty.Register("BackContent", typeof(object), typeof(FlipPanel), null);
private void ChangeVisualState(bool v)
{
if (!this.IsFlipped)
{
VisualStateManager.GoToState(this, "Normal", v);
}
else
{
VisualStateManager.GoToState(this, "Flipped", v);
}
UIElement front = FrontContent as UIElement;
if (front != null)
{
if (IsFlipped)
{
front.Visibility = Visibility.Hidden;
}
else
{
front.Visibility = Visibility.Visible;
}
}
UIElement back = BackContent as UIElement;
if (back != null)
{
if (IsFlipped)
{
back.Visibility = Visibility.Visible;
}
else
{
back.Visibility = Visibility.Hidden;
}
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ToggleButton flipButton = base.GetTemplateChild("FlipButton") as ToggleButton;
if (flipButton != null) flipButton.Click += flipButton_Click;
this.ChangeVisualState(false);
}
private void flipButton_Click(object sender, RoutedEventArgs e)
{
this.IsFlipped = !this.IsFlipped;
}
}
}
4 添加Themes文件夹,并添加默认样式 注意默认在Themes下面创建的资源字典,local会包含Themes,要去掉,否则会提示找不到类型,尽管能运行
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControl">
<Style TargetType="{x:Type local:FlipPanel}">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:FlipPanel}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ViewStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.7" To="Flipped">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FlipButtonTransform"
Storyboard.TargetProperty="Angle" To="90" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</VisualTransition>
<VisualTransition GeneratedDuration="0:0:0.7" To="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FlipButtonTransform"
Storyboard.TargetProperty="Angle" To="-90" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding FrontContent}" />
</Border>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding BackContent}" />
</Border>
<ToggleButton Grid.Row="1" x:Name="FlipButton" RenderTransformOrigin="0.5,0.5"
Margin="0,10,0,0" Width="19" Height="19">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Ellipse Stroke="#FFA9A9A9" Fill="AliceBlue" />
<Path Data="M1,1.5L4.5,5 8,1.5"
Stroke="#FF666666" StrokeThickness="2"
HorizontalAlignment="Center" VerticalAlignment="Center">
</Path>
</Grid>
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.RenderTransform>
<RotateTransform x:Name="FlipButtonTransform" Angle="-90"></RotateTransform>
</ToggleButton.RenderTransform>
</ToggleButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
5 主程序
<Window x:Class="CustomControlApp.FlipPanelTest"
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:CustomControlApp"
xmlns:lib="clr-namespace:CustomControl;assembly=CustomControl"
mc:Ignorable="d"
Title="FlipPanelTest" Height="450" Width="800">
<Grid x:Name="LayoutRoot" Background="White">
<lib:FlipPanel x:Name="panel" BorderBrush="DarkOrange" BorderThickness="3" IsFlipped="True"
CornerRadius="4" Margin="10">
<lib:FlipPanel.FrontContent>
<StackPanel Margin="6">
<TextBlock TextWrapping="Wrap" Margin="3" FontSize="16" Foreground="DarkOrange">This is the front side of the FlipPanel.</TextBlock>
<Button Margin="3" Padding="3" Content="Button One"></Button>
<Button Margin="3" Padding="3" Content="Button Two"></Button>
<Button Margin="3" Padding="3" Content="Button Three"></Button>
<Button Margin="3" Padding="3" Content="Button Four"></Button>
</StackPanel>
</lib:FlipPanel.FrontContent>
<lib:FlipPanel.BackContent>
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Margin="3" FontSize="16" Foreground="DarkMagenta">This is the back side of the FlipPanel.</TextBlock>
<Button Grid.Row="2" Margin="3" Padding="10" Content="Flip Back to Front" HorizontalAlignment="Center" VerticalAlignment="Center" Click="cmdFlip_Click"></Button>
</Grid>
</lib:FlipPanel.BackContent>
</lib:FlipPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Shapes;
namespace CustomControlApp
{
/// <summary>
/// FlipPanelTest.xaml 的交互逻辑
/// </summary>
public partial class FlipPanelTest : Window
{
public FlipPanelTest()
{
InitializeComponent();
}
private void cmdFlip_Click(object sender, RoutedEventArgs e)
{
panel.IsFlipped = !panel.IsFlipped;
}
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容