Pregunta

Tengo una ItemsControl con productos que se añade a través de enlace de datos a una colección observable. Cada elemento tiene una plantilla de datos que define su aspecto.

Estoy tratando de averiguar si es posible aplicar / animaciones / gatillo para cada uno de los ítems de ItemsControl cuando el VisualStateManager pone ItemsControl en un estado particular.

A continuación se muestra una imagen - cuando los elementos de control pasa al estado cerrado - Quiero que los artículos en los elementos de control para reducir el tamaño, así como ocultar el texto y tener un número de hacerse visible. ¿Es esto posible mediante VSM o necesito adjuntar animaciones para cada elemento cuando se crean de forma manual y luego echarlos fuera cuando yo quiero que cambian de estado visual.

texto alternativo http://www.edefine.com/images/misc/drawing1 .jpg

¿Fue útil?

Solución

Esto es posible usando un ObjectAnimationUsingKeyFrames, sin embargo, es estúpidamente difícil de hacer, hará que usted rasgue de los pelos, bloquear el estudio visual con regularidad y le da muy poco en hacerlo de manera sencilla.

La forma más sencilla:

public class TestSwapContentControl : ContentControl 
{
    object StoredOriginalContent;

    public object FullContent
    {
        get { return (object)GetValue(FullContentProperty); }
        set { SetValue(FullContentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FullContent.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FullContentProperty =
        DependencyProperty.Register(
            "FullContent"
            , typeof(object)
            , typeof(TestSwapContentControl)
            , null);

    public void SwitchToFullContent()
    {
        if (FullContent != null)
        {
            StoredOriginalContent = Content;
            Content = FullContent;
        }
    }

    public void SwitchToNormalContent()
    {
        if(StoredOriginalContent != null)
        {
            Content = StoredOriginalContent;
        }
    }
}

A continuación, el xaml de empleo:

    <local:TestSwapContentControl x:Name="mySwitch">
            <Rectangle Height="50" Width="100" Fill="Black" />
        <local:TestSwapContentControl.FullContent>
                <StackPanel>
                    <TextBlock>1</TextBlock>
                    <TextBlock>2</TextBlock>
                    <TextBlock>3</TextBlock>
                    <TextBlock>4</TextBlock>
                    <Rectangle Height="50" Width="100" Fill="Red" />
                </StackPanel>
            </local:TestSwapContentControl.FullContent>
    </local:TestSwapContentControl>   

Con el siguiente cs en la página:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (myTempBool)
        {
            mySwitch.SwitchToFullContent();
            myTempBool = false;
        }
        else
        {
            mySwitch.SwitchToNormalContent();
            myTempBool = true;
        }
    }

Ahora, si realmente se necesita para hacer el control completamente extensible por otros desarrolladores, tendrá que utilizar visualstatemenager, pero es una verdadera perra. Si usted no sabe cómo configurar gestor de estado visual y estados a través de generic.xaml, he aquí una guía de instrucciones:

http: // scorbs.com/2008/06/11/parts-states-model-with-visualstatemanager-part-1-of/

Aquí hay un ejemplo de trabajo, pero no es perfecto ya que parece que no puede establecer el contenido de la ContentPresenter directamente.

using System.Windows;
using System.Windows.Controls;

namespace SilverlightTestApplication
{
    [TemplateVisualState(Name="Normal", GroupName="SizeStates")]
    [TemplateVisualState(Name="Expanded", GroupName="SizeStates")]
    public class TestVSMControl : ContentControl
    {
        public object SmallContent
        {
            get { return (object)GetValue(SmallContentProperty); }
            set { SetValue(SmallContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SmallContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SmallContentProperty =
            DependencyProperty.Register("SmallContent", typeof(object), typeof(TestVSMControl), null);

        public object LargeContent
        {
            get { return (object)GetValue(LargeContentProperty); }
            set { SetValue(LargeContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for LargeContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LargeContentProperty =
            DependencyProperty.Register("LargeContent", typeof(object), typeof(TestVSMControl), null);

        public bool Pressed
        {
            get { return (bool)GetValue(PressedProperty); }
            set { SetValue(PressedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Pressed.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PressedProperty =
            DependencyProperty.Register("Pressed", typeof(bool), typeof(TestVSMControl), 
                new PropertyMetadata(new PropertyChangedCallback(PressedPropertyChanged)));

        static void PressedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var me = sender as TestVSMControl;
            me.ChangeState();
        }

        public TestVSMControl()
        {
            DefaultStyleKey = typeof(TestVSMControl);
        }

        void ChangeState()
        {
            GoToState(true);
        }

        private void GoToState(bool useTransitions)
        {
            if (Pressed)
            {
                VisualStateManager.GoToState(this, "Normal", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Expanded", useTransitions);
            }
        }
    }
}

En su generic.xaml (incluyen xmlns: VSM = "clr-espacio de nombres: System.Windows; montaje = System.Windows"):

<Style TargetType="local:TestVSMControl">        
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:TestVSMControl">
                <StackPanel>
                    <vsm:VisualStateManager.VisualStateGroups>
                        <vsm:VisualStateGroup x:Name="SizeStates">
                            <vsm:VisualState x:Name="Normal">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
                                        <ObjectAnimationUsingKeyFrames.KeyFrames>
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <StackPanel>
                                                        <TextBlock>Rararasputin</TextBlock>
                                                        <Button Content="{TemplateBinding SmallContent}" />
                                                    </StackPanel>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames.KeyFrames>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                            <vsm:VisualState x:Name="Expanded">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
                                         <ObjectAnimationUsingKeyFrames.KeyFrames>
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0"  >
                                                <DiscreteObjectKeyFrame.Value>
                                                    <StackPanel>
                                                        <TextBlock>Other one</TextBlock>
                                                        <Button Content="{TemplateBinding LargeContent}" />
                                                    </StackPanel>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames.KeyFrames>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                        </vsm:VisualStateGroup>
                    </vsm:VisualStateManager.VisualStateGroups>                        
                    <ContentPresenter x:Name="myContentPresenter" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Y cómo utilizar en su página:

            <local:TestVSMControl x:Name="myVSMControl" Height="200">
                <local:TestVSMControl.SmallContent>
                    <Rectangle Height="50" Width="100" Fill="Red" />
                </local:TestVSMControl.SmallContent>
                <local:TestVSMControl.LargeContent>
                    <Rectangle Height="50" Width="100" Fill="Green" />
                </local:TestVSMControl.LargeContent>        
            </local:TestVSMControl>
            <Button Content="Swap" x:Name="VSMButton" Click="VSMButton_Click"  />

con el siguiente en la página:

    private void VSMButton_Click(object sender, RoutedEventArgs e)
    {
        myVSMControl.Pressed = !myVSMControl.Pressed;
    }

Otros consejos

Si usted está hablando sobre el Gestor de Silverlight Visual Estado, me temo que esto no es posible.

VisualStates contienen sólo los objetos Storyboard, que a su vez contienen animaciones. Por lo que yo sé, no se puede cambiar una plantilla con ella.

No estoy seguro acerca de las capacidades de la WPF VisualStateManager.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top