2011-06-03 80 views
20

我有一个主要由图像和按钮组成的控件。我要显示的图像的背面的图像元数据,并具有水平时,按下按钮控制翻页:WPF控制翻转

enter image description here

点击“信息”按钮...

enter image description here

旋转图像围绕轴线180度的视角...

enter image description here

用元数据(或其他任何东西)显示图像的“背面”。

显然,当点击红色的“关闭”按钮时,图像会旋转最后的180度,以便图像再次显示。

我没有做任何3D真的XAML,但我不明白为什么这会是太复杂......

+0

这样做回你想旋转动画吗? – Matt 2011-06-03 14:26:23

+0

是的,没有。我需要能够关闭动画,因为应用程序将在本地和通过远程连接使用。对不起 - 没有说清楚:) – 2011-06-03 14:28:50

回答

10

可以毫不3D来完成。 ScaleEffect1改变水平刻度-1具有相同的视觉效果:

<Image RenderTransformOrigin="0.5,0.5"> 
    <Image.RenderTransform> 
     <ScaleTransform ScaleX="-1" /> 
    </Image.RenderTransform> 
</Image> 

您可以动画ScaleX属性来获取旋转效果。您还应该将它的可用性从Visible更改为Hidden,反之亦然。旋转90度后图像消失。同时后面板应该变得可见。

+0

这只是翻转图像,提问者的形象有一个背面。 – 2011-06-03 14:20:31

+0

是的,但他不能模拟出现图像的背面,使用相同的效果,但以另一种方式? – metalcam 2011-06-03 14:33:35

+0

我可以,但我认为ScaleX本身使旋转看起来非常平坦...只是想弄清楚需要什么歪斜才能给它一些深度:) – 2011-06-03 15:04:54

9

一个用户控件是可翻转的:

<UserControl x:Class="Test.UserControls.FlipControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Test.UserControls" Name="control"> 
    <UserControl.Resources> 
     <ContentControl x:Key="BackSide" Content="{Binding Source={x:Reference control}, Path=Back}" RenderTransformOrigin="0.5,0.5"> 
      <ContentControl.RenderTransform> 
       <ScaleTransform ScaleX="-1" /> 
      </ContentControl.RenderTransform> 
     </ContentControl> 
    </UserControl.Resources> 
    <ContentControl RenderTransformOrigin="0.5,0.5"> 
     <ContentControl.RenderTransform> 
      <TransformGroup> 
       <ScaleTransform x:Name="transform" ScaleX="1" /> 
      </TransformGroup> 
     </ContentControl.RenderTransform> 
     <ContentControl.Style> 
      <Style TargetType="{x:Type ContentControl}"> 
       <Setter Property="Content" Value="{Binding ElementName=control, Path=Front}" /> 
       <Style.Triggers> 
        <DataTrigger Value="True"> 
         <DataTrigger.Binding> 
          <Binding ElementName="transform" Path="ScaleX"> 
           <Binding.Converter> 
            <local:LessThanXToTrueConverter X="0" /> 
           </Binding.Converter> 
          </Binding> 
         </DataTrigger.Binding> 
         <DataTrigger.Setters> 
          <Setter Property="Content" Value="{StaticResource BackSide}"/> 
         </DataTrigger.Setters> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </ContentControl.Style> 
    </ContentControl> 
</UserControl> 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
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; 
using System.ComponentModel; 
using System.Windows.Media.Animation; 

namespace Test.UserControls 
{ 
    /// <summary> 
    /// Interaction logic for FlipControl.xaml 
    /// </summary> 
    public partial class FlipControl : UserControl, INotifyPropertyChanged 
    { 
     public static readonly DependencyProperty FrontProperty = 
      DependencyProperty.Register("Front", typeof(UIElement), typeof(FlipControl), new UIPropertyMetadata(null)); 
     public UIElement Front 
     { 
      get { return (UIElement)GetValue(FrontProperty); } 
      set { SetValue(FrontProperty, value); } 
     } 

     public static readonly DependencyProperty BackProperty = 
      DependencyProperty.Register("Back", typeof(UIElement), typeof(FlipControl), new UIPropertyMetadata(null)); 
     public UIElement Back 
     { 
      get { return (UIElement)GetValue(BackProperty); } 
      set { SetValue(BackProperty, value); } 
     } 

     public static readonly DependencyProperty FlipDurationProperty = 
      DependencyProperty.Register("FlipDuration", typeof(Duration), typeof(FlipControl), new UIPropertyMetadata((Duration)TimeSpan.FromSeconds(0.5))); 
     public Duration FlipDuration 
     { 
      get { return (Duration)GetValue(FlipDurationProperty); } 
      set { SetValue(FlipDurationProperty, value); } 
     } 

     private bool _isFlipped = false; 
     public bool IsFlipped 
     { 
      get { return _isFlipped; } 
      private set 
      { 
       if (value != _isFlipped) 
       { 
        _isFlipped = value; 
        OnPropertyChanged(new PropertyChangedEventArgs("IsFlipped")); 
       } 
      } 
     } 

     private IEasingFunction EasingFunction = new SineEase() { EasingMode = EasingMode.EaseInOut }; 

     public FlipControl() 
     { 
      InitializeComponent(); 
     } 

     public void Flip() 
     { 
      var animation = new DoubleAnimation() 
      { 
       Duration = FlipDuration, 
       EasingFunction = EasingFunction, 
      }; 
      animation.To = IsFlipped ? 1 : -1; 
      transform.BeginAnimation(ScaleTransform.ScaleXProperty, animation); 
      IsFlipped = !IsFlipped; 
      OnFlipped(new EventArgs()); 
     } 

     public event EventHandler Flipped; 

     protected virtual void OnFlipped(EventArgs e) 
     { 
      if (this.Flipped != null) 
      { 
       this.Flipped(this, e); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
     { 
      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, e); 
      } 
     } 
    } 

    public class LessThanXToTrueConverter : IValueConverter 
    { 
     public double X { get; set; } 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return (double)value < X; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 
    } 
} 

用例:

<uc:FlipControl x:Name="fc"> 
    <uc:FlipControl.Front> 
     <Image Source="/Images/Default.ico" /> 
    </uc:FlipControl.Front> 
    <uc:FlipControl.Back> 
     <Image Source="/Images/Error.ico" /> 
    </uc:FlipControl.Back> 
</uc:FlipControl> 
fc.Flip(); 
+0

是的,我一直在尝试X-Scale变换,旋转的外观,因为控制不倾斜,它看起来很平坦。我会继续调查,但为了简单起见,可能会很好地解决这个问题:) – 2011-06-03 15:00:49

+0

我通过翻转两次“固定”翻转的背面问题;你对它的看法是对的,但我怀疑一个简单的扭曲变换会使它看起来不错,而透视变换会更好。 – 2011-06-03 15:16:14

+0

是的,它需要剪切以获得正确的视角,并且要做到这一点需要3D。当我可以证明在UI上花费更多时间时,我会进一步调查它:) – 2011-06-06 07:25:17

0

您可以使用这个想法从这个博客它展示了如何做它在Silverlight中。几乎同样会在WPF工作,如果我们用,而不是投影 http://jobijoy.blogspot.com/2009/04/3d-flipper-control-using-silverlight-30.html

+0

该交互逻辑事情很糟糕,所以虽然这个想法可能没问题,但我会建议几乎完全重写它。 – 2011-06-03 16:37:38

+0

此外,你确定你可以创建一个RenderTransform,其行为如此? – 2011-06-03 16:41:39