2011-06-03 14 views
20

Tengo un control que se compone principalmente de una imagen y un botón. Quiero mostrar los metadatos de imagen en la parte posterior de la imagen y tener el control de flip horizontal cuando se pulsa el botón:control WPF tirón

enter image description here

Haga clic en el botón es decir, "info" ...

enter image description here

girar la imagen 180 DEGS alrededor del eje ...

enter image description here

Show "vuelta" de la imagen con los metadatos (o lo que sea realmente).

Obviamente, cuando se hace clic en el botón rojo "estrecha", la imagen gira en torno a los últimos 180 DEGS para que la imagen está mostrando de nuevo.

No he hecho ninguna 3D realmente en XAML, pero no puedo ver por qué esto sería demasiado complejo ...

+0

¿Quieres animar la rotación? – Matt

+0

Sí y no. Necesito poder desactivar la animación ya que la aplicación se usará localmente y a través de una conexión remota. Lo siento, no lo dejé claro :) –

Respuesta

10

Se puede hacer sin 3D. ScaleEffect con el cambio de escala horizontal de 1 a -1 tiene el mismo efecto visual:

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

Puede animar ScaleX propiedad para obtener rotación efecto. También debe cambiar su visibilidad de Visible a Hidden y viceversa. Para hacer que la imagen desaparezca después de girar 90 grados. Al mismo tiempo, el panel posterior debería ser visible.

+0

Esto solo voltea la imagen, la imagen del asker tiene una parte trasera. –

+0

Sí, pero ¿no podría simular una aparición de la parte posterior de la imagen, utilizando el mismo efecto, pero por el otro lado? – metalcam

+0

Puedo hacerlo, pero creo que ScaleX solo hace que la rotación se vea muy plana ... Solo trato de descubrir qué sesgo se necesita para darle un poco de profundidad :) –

1

Tener un look at this project.

Estoy a la espera de las proyecciones planas de Silverlight que vienen a WPF.

9

un control de usuario que es flippable:

<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(); 
     } 
    } 
} 

Ejemplo de uso:

<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

Sí, he estado tratando de transformar X-Scale y mientras se da una apariencia de rotación, porque el control no se tuerce, parece parecer bastante plano. Continuaré investigando, pero podría resolver esto por simplicidad :) –

+0

"Solucioné" el problema de la parte posterior volteada al voltearlo dos veces; Estás en lo correcto al decir que se ve plano, pero dudo que una simple transformación sesgada lo haga quedar bien, una transformación de perspectiva sería mejor. –

+0

Sí, necesita esquilar realmente para obtener la perspectiva adecuada y para hacerlo requiere 3D. Lo investigaré más a fondo cuando pueda justificar el gasto de más tiempo en la interfaz de usuario :) –

0

Puede utilizar la idea de este blog que muestra cómo hacerlo en Silverlight. Prácticamente mismo funcionará en WPF si utilizamos Viewport3D en lugar de proyección http://jobijoy.blogspot.com/2009/04/3d-flipper-control-using-silverlight-30.html

+0

La lógica de interacción de ese La cosa es abismal, así que aunque la idea podría estar bien, sugeriría que la reescribiera completamente. –

+0

Además, ¿está seguro de que puede crear una RenderTransform que se comporte así? –