This is a migrated thread and some comments may be shown as answers.

Make CarouselItem Pop Out of bounds

7 Answers 95 Views
Carousel
This is a migrated thread and some comments may be shown as answers.
Boots
Top achievements
Rank 1
Boots asked on 17 Dec 2009, 04:54 PM
Hello,

I recently got a task to make an item in the carousel grow when the IsMouseOver property is true. I can get the item to grow but since its contained inside of a scrollviewer i cant see the entire item when it grows. i did get it to work via popup but i was wondering if you had any other ideas on how this could be accomplished other than making the scrollviewer grow too. we'd like that to stay the same size.

I also got it to do exactly what i wanted using the RadCarouselPanel but when i have say... 10,000 records to display loading time becomes an issue.

here is the usercontrol I'm populating the carousel with

<UserControl x:Class="WpfApplication1.CarouselItem" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    MouseDown="UserControl_MouseDown" 
    Width="120" > 
    <Grid> 
        <Grid.RenderTransform> 
            <ScaleTransform ScaleX="1" ScaleY="1" /> 
        </Grid.RenderTransform> 
        <Grid.Style> 
            <Style TargetType="Grid"
                <Style.Triggers> 
                    <Trigger Property="IsMouseOver" Value="True"
                        <Trigger.EnterActions> 
                            <BeginStoryboard> 
                                <Storyboard> 
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)" 
                                        To="2"  
                                        BeginTime="0:0:0.5" 
                                        Duration="0:0:0.3"/> 
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" 
                                        To="2"  
                                        BeginTime="0:0:0.5" 
                                        Duration="0:0:0.3"/> 
                                </Storyboard> 
                            </BeginStoryboard> 
                        </Trigger.EnterActions> 
                        <Trigger.ExitActions> 
                            <BeginStoryboard> 
                                <Storyboard> 
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)" 
                                        To="1" 
                                        Duration="0:0:0.3"/> 
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" 
                                        To="1"  
                                        Duration="0:0:0.3"/> 
                                </Storyboard> 
                            </BeginStoryboard> 
                        </Trigger.ExitActions> 
                    </Trigger> 
                </Style.Triggers> 
            </Style> 
        </Grid.Style> 
        <Border 
            CornerRadius="5" 
            BorderBrush="Black" 
            BorderThickness="2"
            <Image Source="pics\GreenDoor.png" Stretch="Fill" /> 
        </Border> 
    </Grid> 
</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; 
 
namespace WpfApplication1 
    /// <summary> 
    /// Interaction logic for UserControl1.xaml 
    /// </summary> 
    public partial class CarouselItem : UserControl 
    { 
        public delegate void ItemsMouseDown(object sender); 
        public event ItemsMouseDown ItemMouseDown; 
 
        public CarouselItem() 
        { 
            try 
            { 
                InitializeComponent(); 
            } 
            catch (Exception ex) 
            { 
                MessageBox.Show(ex.ToString()); 
            } 
        } 
 
        private void UserControl_MouseDown(object sender, MouseButtonEventArgs e) 
        { 
            if (ItemMouseDown != null
                ItemMouseDown(this); 
        } 
    } 
 

any ideas would be helpful
thanks much,
~Boots

7 Answers, 1 is accepted

Sort by
0
Milan
Telerik team
answered on 18 Dec 2009, 10:28 AM
Hello Boots,

It is possible to apply scaling to all items at the same time - the way to do this is to apply scaling to the RadCarouselPanel. For example:

<telerik:RadCarousel Name="RadCarousel1">
    <telerik:RadCarousel.ItemsPanel>
        <ItemsPanelTemplate>
            <telerik:RadCarouselPanel x:Name="carouselPanel" IsItemsHost="True" 
                                      RenderTransformOrigin="0.5, 0.5" ItemsPerPage="7">
                <telerik:RadCarouselPanel.RenderTransform>
                    <ScaleTransform ScaleX="2" ScaleY="2" />
                </telerik:RadCarouselPanel.RenderTransform>
            </telerik:RadCarouselPanel
        </ItemsPanelTemplate>
    </telerik:RadCarousel.ItemsPanel>
</telerik:RadCarousel>

In regard to the performance issue with a large data set, we were unable to reproduce the problem. If you could send us your application we could take a look and try to solve the problem.

Best wishes,

Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Boots
Top achievements
Rank 1
answered on 18 Dec 2009, 03:05 PM
Hello Milan,

Thanks for getting back to me so quickly. We're looking to only make one item grow at a time. The problem I'm running into is the items are contained inside of the RadCarousel. so when the column that contains RadCarousel has a set width of 150 and i want the item to grow to say 300 half of the item is cut off by the RadCarousel. i did get it to expand grow outside of its bounds using only the RadCaouselPanel tags without a RadCaousel and adding the children manually. This is when i would run into the issue with loading time. i was wondering if you had a more elegant solution.

what i'm looking for is somthing like
<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"
    <Grid> 
        <Grid.ColumnDefinitions> 
            <ColumnDefinition /> 
            <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 
        <Grid Background="Blue" Grid.Column="1"
             
        </Grid> 
        <Grid Background="Green"
            <Label Content="Hover Over Me" HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="False"
                <Label.RenderTransform> 
                    <ScaleTransform ScaleX="1" ScaleY="1" /> 
                </Label.RenderTransform> 
                <Label.Style> 
                    <Style TargetType="Label"
                        <Style.Triggers> 
                            <Trigger Property="IsMouseOver" Value="True"
                                <Trigger.EnterActions> 
                                    <BeginStoryboard> 
                                        <Storyboard> 
                                            <DoubleAnimation  
                                                Storyboard.TargetProperty="(Label.RenderTransform).(ScaleTransform.ScaleX)"  
                                                To="2"   
                                                BeginTime="0:0:0.5"  
                                                Duration="0:0:0.3"/> 
                                            <DoubleAnimation  
                                                Storyboard.TargetProperty="(Label.RenderTransform).(ScaleTransform.ScaleY)"  
                                                To="2"   
                                                BeginTime="0:0:0.5"  
                                                Duration="0:0:0.3"/> 
                                        </Storyboard> 
                                    </BeginStoryboard> 
                                </Trigger.EnterActions> 
                                <Trigger.ExitActions> 
                                    <BeginStoryboard> 
                                        <Storyboard> 
                                            <DoubleAnimation  
                                        Storyboard.TargetProperty="(Label.RenderTransform).(ScaleTransform.ScaleX)"  
                                        To="1"  
                                        Duration="0:0:0.3"/> 
                                            <DoubleAnimation  
                                        Storyboard.TargetProperty="(Label.RenderTransform).(ScaleTransform.ScaleY)"  
                                        To="1"   
                                        Duration="0:0:0.3"/> 
                                        </Storyboard> 
                                    </BeginStoryboard> 
                                </Trigger.ExitActions> 
                            </Trigger> 
                        </Style.Triggers> 
                    </Style> 
                </Label.Style> 
            </Label> 
        </Grid> 
    </Grid> 
</Window> 
 

where the green is the carousel and the label is the Item. when you hover over the item it expands beyond its bounds.

Thanks much
~Boots
0
Boots
Top achievements
Rank 1
answered on 22 Dec 2009, 05:40 PM
Hello Milan,
after some trial and error i got it to work. I edited the template for the CarouselItem. to get rid of the default border. Then in the CarouselDataRecordPresenter i added a popup to the template. we were already using our own usercontrol to display the records. added animation to grow after 3/10 of a second.

 my xaml looks like this
<Style TargetType="{x:Type telerik:CarouselDataRecordPresenter}"
        <Setter Property="IsTabStop" Value="False" /> 
        <Setter Property="Template"
            <Setter.Value> 
                <ControlTemplate TargetType="{x:Type telerik:CarouselDataRecordPresenter}"
                    <Grid>
                    <!--the width and height of the usercontrol is 160 so it shouldnt go any bigger than the popup-->
                        <Popup 
                            x:Name="Part_Popup" 
                            PlacementRectangle="0,0,0,0" 
                            AllowsTransparency="True" 
                            Height="320" 
                            Width="320"
                            <Border 
                                x:Name="Part_PopupBorder" 
                                Background="{DynamicResource CarouselBackBrush}" 
                                BorderBrush="Black" 
                                BorderThickness="1" 
                                CornerRadius="5"  
                                HorizontalAlignment="Left" 
                                VerticalAlignment="Top" 
                                Height="{TemplateBinding ActualHeight}" 
                                Width="{TemplateBinding ActualWidth}"
                                <Border.RenderTransform> 
                                    <ScaleTransform ScaleX="1" ScaleY="1" /> 
                                </Border.RenderTransform> 
                                <local:CarouselItem DataContext="{Binding}" /> 
                            </Border> 
                        </Popup> 
                        <Border 
                            x:Name="Part_Border" 
                            Background="{DynamicResource CarouselBackBrush}" 
                            BorderBrush="Black" 
                            BorderThickness="1" 
                            CornerRadius="5"
                            <local:CarouselItem DataContext="{Binding}" /> 
                        </Border> 
                    </Grid> 
                    <ControlTemplate.Triggers> 
                        <Trigger SourceName="Part_Popup" Property="IsMouseOver" Value="True"
 
                            <Trigger.Setters> 
                                <Setter TargetName="Part_Popup" Property="IsOpen" Value="True" /> 
                            </Trigger.Setters> 
                            <Trigger.EnterActions> 
                                <BeginStoryboard x:Name="PopUpStoryBoard"
                                    <Storyboard> 
                                         
                                        <DoubleAnimation 
                                            Storyboard.TargetName="Part_Border" 
                                            Storyboard.TargetProperty="(Border.Opacity)" 
                                            From="1" 
                                            To="0.25"  
                                            BeginTime="0:0:0.5" 
                                            Duration="0:0:0.3" /> 
                                         
                                        <DoubleAnimation 
                                            Storyboard.TargetName="Part_PopupBorder" 
                                            Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)" 
                                            From="1" 
                                            To="2"  
                                            BeginTime="0:0:0.5" 
                                            Duration="0:0:0.3" /> 
                                         
                                        <DoubleAnimation 
                                            Storyboard.TargetName="Part_PopupBorder" 
                                            Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleY)" 
                                            From="1" 
                                            To="2"  
                                            BeginTime="0:0:0.5" 
                                            Duration="0:0:0.3" /> 
                                         
                                        <ColorAnimation 
                                            Storyboard.TargetName="Part_PopupBorder" 
                                            Storyboard.TargetProperty="Background.GradientStops[0].Color" 
                                            To="#FFFAFBFE" Duration="0:0:0.3" /> 
                                         
                                        <ColorAnimation 
                                            Storyboard.TargetName="Part_PopupBorder" 
                                            Storyboard.TargetProperty="Background.GradientStops[2].Color" 
                                            To="#FFC4DBF6" Duration="0:0:0.3" /> 
                                         
                                    </Storyboard> 
                                </BeginStoryboard> 
                            </Trigger.EnterActions> 
                            <Trigger.ExitActions> 
                                <StopStoryboard BeginStoryboardName="PopUpStoryBoard" /> 
                            </Trigger.ExitActions> 
                        </Trigger> 
                         
                        <Trigger SourceName="Part_Border" Property="IsMouseOver" Value="True"
                            <Trigger.Setters> 
                                <Setter TargetName="Part_Popup" Property="IsOpen" Value="True" /> 
                            </Trigger.Setters> 
                        </Trigger> 
                    </ControlTemplate.Triggers> 
                </ControlTemplate> 
            </Setter.Value> 
        </Setter> 
    </Style> 

let me know if you have a better solution.

Thanks much,
Boots


0
Milan
Telerik team
answered on 25 Dec 2009, 09:53 AM
Hello Boots,

Glad that you have found a working solution. Could you please share the XAML code of the customized CarouselItem? It is a bit strange to see CarouselItem inside CarouselDataRecordPresenter and there might be a better solution.


Kind regards,
Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Boots
Top achievements
Rank 1
answered on 28 Dec 2009, 02:38 PM
Hello Milan,

Here is the xaml you asked for along with the code behind.
<UserControl x:Class="Carousel.CarouselItem" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    <Grid Name="MainGrid"
        <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="Auto" /> 
            <ColumnDefinition Width="*" /> 
        </Grid.ColumnDefinitions> 
    </Grid> 
</UserControl> 

In the code behind I'm using reflection to add rows to the customize CarouselItem based on the business object that its using as the datacontext. Unfortunately populating it this way there is no telling what order the properties for the business object will be in.
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.Reflection; 
 
namespace Carousel 
    /// <summary> 
    /// Interaction logic for CarouselItem.xaml 
    /// </summary> 
    public partial class CarouselItem : UserControl 
    { 
        public CarouselItem() 
        { 
            InitializeComponent(); 
            this.DataContextChanged += new DependencyPropertyChangedEventHandler(CarouselItem_DataContextChanged); 
        } 
 
        private void CarouselItem_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
        { 
            Object Item = this.DataContext; 
            if (Item != null
            { 
                PropertyInfo[] propertyInfo = Item.GetType().GetProperties(); 
 
                int i = 0; 
                foreach (PropertyInfo p in propertyInfo) 
                { 
                    MainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); 
 
                    Label lblLabel = new Label() 
                    { 
                        Content = p.Name, 
                        FontSize = 8 
                    }; 
                    lblLabel.SetValue(Grid.ColumnProperty, 0); 
                    lblLabel.SetValue(Grid.RowProperty, i); 
 
                    MainGrid.Children.Add(lblLabel); 
 
                    Label lblData = new Label(); 
                    lblData.FontSize = 12; 
                    if (p.GetValue(Item, null) != null
                        lblData.Content = p.GetValue(Item, null).ToString(); 
 
                    lblData.SetValue(Grid.ColumnProperty, 1); 
                    lblData.SetValue(Grid.RowProperty, i++); 
 
                    MainGrid.Children.Add(lblData); 
                } 
            } 
        } 
    } 
 

Looking back on this I bet we could add a trigger and a popup to the customized CarouselItem itself instead of to the CarouselDataRecordPresenter.

Thanks Again,
~Boots



0
Accepted
Milan
Telerik team
answered on 05 Jan 2010, 11:35 AM

Hello Boots,

I guess you could try to eliminate the reflection part. In case you have a small finite number of data types you can create DataTemplates for all of you data types. Once you do that you can turn off the automatic presenter generation of RadCarousel. By doing that WPF will automatically decide which template to use based on the data type that is being use. For example:

<Grid>
    <Grid.Resources>
          
        <DataTemplate DataType="{x:Type local:Message}">
            <Border Background="Red">
                <TextBlock Text="{Binding Sender}"/>
            </Border>
        </DataTemplate>
          
        <DataTemplate DataType="{x:Type local:Person}">
            <Border Background="Green">
                <TextBlock Text="{Binding Name}"/>
            </Border>
        </DataTemplate>
          
    </Grid.Resources>
      
    <telerik:RadCarousel Name="RadCarousel1" AutoGenerateDataPresenters="False"/>
      
</Grid>

With this setup when Person elements are added to the carousel WPF will automatically load the DataTemplate for the Person type. And similarly when Message elements are added the other template will be used.

The only difficulty here is to decide where to put the Popup code. One possible place is the CarouselItemContentPresenter:

<Style TargetType="telerik:CarouselItemContentPresenter">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="telerik:CarouselItemContentPresenter">
                <Grid>
                    <!--the width and height of the usercontrol is 160 so it shouldnt go any bigger than the popup-->
                    <Popup 
                x:Name="Part_Popup" 
                PlacementRectangle="0,0,0,0" 
                AllowsTransparency="True" 
                Height="520" 
                Width="520">
                        <Border 
                    x:Name="Part_PopupBorder" 
                    Background="{DynamicResource CarouselBackBrush}" 
                    BorderBrush="Black" 
                    BorderThickness="1" 
                    CornerRadius="5"  
                    HorizontalAlignment="Left" 
                    VerticalAlignment="Top" 
                    Height="{TemplateBinding ActualHeight}" 
                    Width="{TemplateBinding ActualWidth}">
                            <Border.RenderTransform>
                                <ScaleTransform ScaleX="1" ScaleY="1" />
                            </Border.RenderTransform>
                            <ContentPresenter Content="{Binding}"/>
                        </Border>
                    </Popup>
                    <Border 
                x:Name="Part_Border" 
                Background="{DynamicResource CarouselBackBrush}" 
                BorderBrush="Black" 
                BorderThickness="1" 
                CornerRadius="5">
                        <ContentPresenter Content="{Binding}"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="Part_Popup" Property="IsMouseOver" Value="True">
  
                        <Trigger.Setters>
                            <Setter TargetName="Part_Popup" Property="IsOpen" Value="True" />
                        </Trigger.Setters>
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="PopUpStoryBoard">
                                <Storyboard>
  
                                    <DoubleAnimation 
                                Storyboard.TargetName="Part_Border" 
                                Storyboard.TargetProperty="(Border.Opacity)" 
                                From="1" 
                                To="0.25"  
                                BeginTime="0:0:0.5" 
                                Duration="0:0:0.3" />
  
                                    <DoubleAnimation 
                                Storyboard.TargetName="Part_PopupBorder" 
                                Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)" 
                                From="1" 
                                To="2"  
                                BeginTime="0:0:0.5" 
                                Duration="0:0:0.3" />
  
                                    <DoubleAnimation 
                                Storyboard.TargetName="Part_PopupBorder" 
                                Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleY)" 
                                From="1" 
                                To="2"  
                                BeginTime="0:0:0.5" 
                                Duration="0:0:0.3" />
  
                                    <!--<ColorAnimation 
                                Storyboard.TargetName="Part_PopupBorder" 
                                Storyboard.TargetProperty="Background.GradientStops[0].Color" 
                                To="#FFFAFBFE" Duration="0:0:0.3" />
  
                                    <ColorAnimation 
                                Storyboard.TargetName="Part_PopupBorder" 
                                Storyboard.TargetProperty="Background.GradientStops[2].Color" 
                                To="#FFC4DBF6" Duration="0:0:0.3" />-->
  
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <StopStoryboard BeginStoryboardName="PopUpStoryBoard" />
                        </Trigger.ExitActions>
                    </Trigger>
  
                    <Trigger SourceName="Part_Border" Property="IsMouseOver" Value="True">
                        <Trigger.Setters>
                            <Setter TargetName="Part_Popup" Property="IsOpen" Value="True" />
                        </Trigger.Setters>
                    </Trigger>
                </ControlTemplate.Triggers>
                  
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I am not sure if this is applicable to your scenario but it might help you eliminate the nasty reflection part.


Greetings,
Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Boots
Top achievements
Rank 1
answered on 06 Jan 2010, 03:41 PM
Hello Milan ,
I like the DataTemplate idea much better than the reflection idea. Using the DataTemplate will give us a lot more freedom in the future.

Thanks Again,
~Boots
Tags
Carousel
Asked by
Boots
Top achievements
Rank 1
Answers by
Milan
Telerik team
Boots
Top achievements
Rank 1
Share this question
or