I'm trying to implement a nice-looking horizontally scrolled gridview inside my app. I have already implemented it using the Q42.WinRT library like this:
<Canvas>
<StackPanel Orientation="Horizontal" Height="768">
<StackPanel.RenderTransform>
<CompositeTransform
TranslateX="{Binding ElementName=MyScrollViewer, Path=HorizontalOffset, Converter={StaticResource ParallaxConverter}}" />
</StackPanel.RenderTransform>
<Image Source="/Assets/3.jpg" Width="1366" Stretch="UniformToFill"/>
<Image Source="/Assets/1.jpg" Stretch="UniformToFill"/>
<Image Source="/Assets/2.jpg" Stretch="UniformToFill"/>
</StackPanel>
</Canvas>
<ScrollViewer
x:Name="MyScrollViewer"
HorizontalScrollMode="Enabled"
HorizontalScrollBarVisibility="Auto"
VerticalScrollMode="Disabled"
VerticalAlignment="Center"
Height="768">
<GridView>
//...my gridview goes here
</GridView> </ScrollViewer>
Everything works fine, however in my app I need to use semantic zoom, and I found that semantic zoom does NOT WORK properly when put inside a ScrollViewer.
Generally all the solutions for parallactic backgrounds that I found on the internet implement some kind of functionality over a scrollviewer, which is unfortunate for me as I cannot use it.
Can anybody think of another way to achieve the desired effect?
Generally putting GridViews inside a ScrollViewer is not a great idea since they already have ScrollViewers inside of them...
You should put your 2 GridViews inside a SemanticZoom.
Perhaps you could edit the template for your GridView and put a parallax background in there - perhaps as a Canvas with some content that responds to the ViewChanged events on the GridView.
EDIT*
You inspired me to try to write a ParallaxBackgroundBehavior for the Toolkit. :)
You can see an early version here. There is also a sample included.
Related
Using Windows Template Studio, I created a (mostly auto-generated) sample UWP application, which shows a bunch of Images within a GridView.
In order to rotate them, I've used the following xaml - note RenderTransform block which I've added, and the comments within that scope:
<Grid x:Name="ContentArea">
<GridView
x:Name="ImagesGridView"
ItemsSource="{x:Bind Source}"
IsItemClickEnabled="True"
Padding="{StaticResource MediumLeftRightMargin}"
SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate x:DataType="models:SampleImage">
<Image
x:Name="galleryImage"
Style="{StaticResource ThumbnailImageStyle}"
Source="{x:Bind Source}"
AutomationProperties.Name="{x:Bind Name}"
ToolTipService.ToolTip="{x:Bind Name}">
<Image.RenderTransform> <!-- That's the part which I've added, on top of the auto-generated xaml -->
<RotateTransform Angle="90" CenterX="114" CenterY="114" /> <!-- because the ThumbnailImageStyle defines width and height as 228 -->
</Image.RenderTransform>
</Image>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
So that worked fine - until I tried non-square photos.
At this stage, the result was that the image itself would sometimes show outside of its container within the grid:
I've tried:
To use different values for the CenterX and CenterY fields (according to the grid's item size, according to the original image size, or just "0.5, 0.5"), but that didn't solve the case.
To use Image.LayoutTransform (as suggested here), but it doesn't seem to be available in a Universal Application (or perhaps I'm missing some reference?).
Noticed that when I click on the problematic images, they will suddenly move back to their expected location within the grid (and also sometimes the rotation will be gone, so its back to the original image).
Eventually, I solved it by rotating the image in the code-behind (like here), before adding it to the binded source of the GridView - but shouldn't there be a proper way to achieve that just by using the xaml itself?
So that worked fine - until I tried non-square photos. At this stage, the result was that the image itself would sometimes show outside of its container within the grid:
If u want the image will rotate with center and it will not display outside GridView. you could set RenderTransformOrigin property.
<Image Width="100" Height="100" RenderTransformOrigin="0.5,0.5"
Source="{Binding}">
<Image.RenderTransform>
<!-- That's the part which I've added, on top of the auto-generated xaml -->
<RotateTransform Angle="90" />
<!-- because the ThumbnailImageStyle defines width and height as 228 -->
</Image.RenderTransform>
</Image>
Update
When the GridView item clicked, the default Pressed visual statue will make the content of gridview re-layout. Currently, there is a workaround that use GridViewItemExpanded style.
<GridView ItemContainerStyle="{StaticResource GridViewItemExpanded}"
I'm trying to get a ContentControl to apply a ContentThemeTransitionwhere the content will be a string, so when the string changes via a binding the new string will animate in. I can't use ContentThemeTransition with a TextBlock as this doesn't derive from ContentControl.
Here is some example XAML that shows the problem. If I edit the text in the Textbox (which represents the text in my ViewModel that the ContentControl is really bound to) I would expect the Text shown in the ContentControl to animate in, but it doesn't.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="text" Text="Hello" Width="100" Height="30"/>
<ContentControl Grid.Row="1" Width="100" Height="100" Content="{Binding ElementName=text , Path=Text}">
<ContentControl.Transitions>
<TransitionCollection>
<ContentThemeTransition HorizontalOffset="40"/>
</TransitionCollection>
</ContentControl.Transitions>
</ContentControl>
</Grid>
What am I doing wrong?
Update
I am getting somewhere now. If you replace the ContentControl XAML to
<ContentPresenter Background="Black" Foreground="Red" Grid.Row="1" Width="100" Height="100" Content="{Binding ElementName=text , Path=Text}">
<ContentPresenter.ContentTransitions>
<TransitionCollection>
<ContentThemeTransition VerticalOffset="-100"/>
</TransitionCollection>
</ContentPresenter.ContentTransitions>
</ContentPresenter>
then it works. Oddly, with the VerticalOffset =-100 as above the new value animates down outside of the ContentControli.e. its visible outside the bounds of the control. Anyone know how to change things so the animation only appears within the confines of the ContentPresenter?
Tested by my side, your first <ContentThemeTransition HorizontalOffset="40"/> and second <ContentThemeTransition VerticalOffset="-100"/> both work but only for the first time, you can enlarge the HorizontalOffset for testing and check if it works.
Since you expected that the animation should work every time the text is changed, I think you will need to create a animation which targets the Text of TextBlock directly instead of targeting the Content of ContentControl.
In this scenario, XAML Behaviors will be a good helper. You can refer to #Jerry Nixon - MSFT's answer in thread: How to animate TextBlock when its value changes in WinRT XAML?
Update:
My mistake that I only noticed that you changed HorizontalOffset to VerticalOffset. You actually also changed ContentControl to ContentPresenter.
According to the UI coordinate of UWP, since your animation target the ContentPresenter, then consider the left-top point of your ContentPresent is (0, 0). When you set <ContentThemeTransition VerticalOffset="-100"/>, it will transit from up (0, -100) back to (0, 0) and it will definitely animate outside of your ContentPresent, I think it is designed to be so, and we're not able change it. Here I can only suggest that modifying the transition from down to up like <ContentThemeTransition VerticalOffset="100"/>, it will help a little here but eventually it changes your animation, so I don't think this will be a good approach.
I'm applying EntranceThemeTransition to StackPanel that contains bunch of controls. When I show a popup everything works fine except TextBlocks that jump a little after animation.
Here is a video of that:
http://screencast.com/t/VXSiti6Mh
Here is code I'm using:
<StackPanel Margin="40">
<StackPanel.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition FromHorizontalOffset="100" />
</TransitionCollection>
</StackPanel.ChildrenTransitions>
<TextBlock Text="Filter Results" />
<TextBlock >Show</TextBlock>
</StackPanel>
The popup itself has PaneThemeTransition set as it's Transition.
Any ideas why it could be happening?
Have you tried:
UseLayoutRounding="True" SnapsToDevicePixels="True"
on the container.
I found a workaround - wrap each textblock with StackPanel. Clearly it's not ideal but it works.
I still wonder if there is a way to fix it without hacks...
OK, so I have this image that's 1000x500. So I'm displaying it in WP7 like this:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0" Background="{StaticResource PhoneAccentBrush}">
<Image Name="image1" />
</Grid>
And after I set the image's contents in code, it renders like this:
Not bad, but my business requirement is to display it vertically, so I need to rotate it. Easy enough:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0" Background="{StaticResource PhoneAccentBrush}">
<Image Name="image1" RenderTransformOrigin="0.5 0.5">
<Image.RenderTransform>
<RotateTransform Angle="90"></RotateTransform>
</Image.RenderTransform>
</Image>
</Grid>
And the result is:
OK that's the idea, but I want the image to stretch as much as possible. The image is larger than the screen's dimensions so it should be easy.
Instead, it looks like what's happening is that the image takes on the dimensions of what it would be when it fills the screen horizontally, then that is what gets rotated.
OK, so they've got this "Stretch" parameter. Let's see what that does.
Well, setting it to "Uniform" does nothing
Setting it to "Fill" does this:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0" Background="{StaticResource PhoneAccentBrush}">
<Image Name="image1" RenderTransformOrigin="0.5 0.5" Stretch="Fill">
<Image.RenderTransform>
<RotateTransform Angle="90"></RotateTransform>
</Image.RenderTransform>
</Image>
</Grid>
Looks like it's just stretching the rotated image horizontally, which isn't what I want.
And "UniformToFill" does this:
I don't even know what happened there.
I must say, after having programmed this App for iOS and Android and now doing the WP7 version on a lark since my speciality for a decade now has been in C#, Microsoft really nailed a whole lot of stuff with WP7. It's simple to work with and it's clear they've put a ton of work in it and have successfully leveraged their existing technology into it (.NET CE, Silverlight, etc.)
So it's baffling why after blowing through everything else in this App, I can't get a simple image to rotate and scale.
Anyone have any idea what I'm missing or doing wrong here? All I need is it to rotate 90 degrees and then fill the screen, so the more elaborate rotation solutions I've seen for WP7 don't really apply here.
The problem with RenderTransform is that it does NOT propagate the change in size/orientation to the parent controls. In WPF there is LayoutTransform which accomplishes this.
Luckily you are not alone and the Silverlight toolkit provides a solution called: LayoutTransformer
For the windows Phone you can find a port by David Anson here
I am attempting to convert a bing map implementation that uses standard PushPins in order to populate the map, but I need to add a tooltip to each pin. I found some options of how to do this on the website but the issue is I need the pushpins to be different from each other in a way that is dynamic. Based on the properties of each pin it must have a different background color.
The code already on this site all has the programmer use an image of the pushpin when they customize it.
So right now I need a way to either create a templated pushpin that is able to maintain the look and properties of a pushpin (so I can set background), while allowing a tooltip. Or instead having a regular pushpin have a tooltip or popup with it.
Any help would be appreciated!
Edited:
Control Template I am using
<ControlTemplate x:Key="NewPins" >
<Grid x:Name="pushPin" >
<Popup IsOpen="False" behaviors:RolloverPopup.HideDelay="0" behaviors:RolloverPopup.Target="{Binding ElementName=pushPin}" Margin="30,-20,0,0" >
<Border Background="White" BorderBrush="Black" CornerRadius="10" BorderThickness="1">
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding Title}" Foreground="Black" FontWeight="Bold" TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" />
<TextBlock Text="{Binding Content}" Foreground="Black" TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" />
</StackPanel>
</Border>
</Popup>
</Grid>
</ControlTemplate>
This is setting up the pin in C#
Pushpin pin = new Pushpin()
{
Location = new Location( Double.Parse(item.PinLat), Double.Parse(item.PinLong)),
Content=String.Concat( GetNewlineString(item.LocationName), GetNewlineString(item.CallerName), GetNewlineString(item.PhoneNumber)),
Template=(ControlTemplate)Application.Current.Resources["NewPins"],
Width = 50,
Height = 65,
};
And this is creating the Bing Map
<c:BingMapAdSmart
AnimationLevel="UserInput"
Pins="{Binding DashboardViewModel.MapPins}"
NavigationVisibility="Visible"
SetViewZoomFactor="0"
MaxZoomLevel="7"
Visibility="{Binding NavViewModel.IsViewTransitioning, Converter={StaticResource TrueToCollapsedConverter}}" />
I may not really understand your question correctly, but i assume you need pushpins that are being created dynamically based on a template right? And you want to be able to change the tooltip (content property i assume) independently.
If thats the case, first you need to put a template resource to your resources in xaml;
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="template_name" TargetType="m:Pushpin">
...this is your design part you can compile this xaml via Expression
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
then you'll need pass this value to every pushpin you've created dynamically codebehind. On this stage you can also set their content property, since they don't have a notification property, i don't know if you mean this but content property is the similar one. You can edit them like you edit other stuff;
myPushPin.template = (ControlTemplate)This.Resources["template_name"];
myPushPin.Content = "Hello World!";
This stage may differ according where you put your resources if its in phone:PhoneApplicationPage.Resources
if you put in Application.Resources
use this;
myPushPin.template = (ControlTemplate)Application.Current.Resources["template_name"];
myPushPin.Content = "Hello World!";
This should work, i don't have bing maps API or WP7 tools installed on this computer so i can't test it but this should be ok.
Happy coding!
Edit:
So if you want to change the background of a pushpin you don't have to hold back, it doesn't matter whether it has a control template or not. Actually every control has one as default. You can change the background as you always do
myPushpin.Background = new SolidColorBrush(Colors.Blue);
I have done exactly what you describe. The way i did this makes the most sense to me. Here is what I did:
I created a custom Pushpin (i.e. UserControl). This Xaml defines my custom pushpin. It assumes this pushpin is to be data-bound to. One of the binded properties is background Color. This will easily satisfy your dynamic color issue.
In the bing map control i defined the following:
The MyPushpinTemplate is defined in the UserControl.Resources like this:
MyPushpinControl is the UserControl.
I also have a data model class (that implements INotifyPropertyChanged). This class is bound to an instance of MyPushpinControl. this data model class has all the properties and is data-binded to the UserControl.
This is technically all you need to know.
To satisfy your tooltip issue, I simply added a tooltip to one of the panels within my custom pushpin. Simple as that.
Until I have a better solution I have decided the only thing I can think to do is to create a number of different pins to use. I don't need an infinite color solution so about 15 different pins should do the trick. Messy but it will work.
I just solved this issue to my complete satisfaction. To accomplish this, you need to have to create a Pushpin style with a key. Then inside this pushpin you create a standard pushpin (you can use another style on that but don't let it look back to this style, I used default), and a popup to go along with it. An example is below, I am using a local tool to do easy rollover popups, otherwise its standard stuff + bind maps.
<Style TargetType="bingMaps:Pushpin" x:Key="NewPins2">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="bingMaps:Pushpin" >
<Grid x:Name="pushPin" >
<Border Width="50" Height="65" >
<bingMaps:Pushpin Background="{TemplateBinding Background}" />
</Border>
<Popup IsOpen="False" behaviors:RolloverPopup.HideDelay="0" behaviors:RolloverPopup.Target="{Binding ElementName=pushPin}" Margin="30,-20,0,0" >
<Border Background="White" BorderBrush="Black" CornerRadius="10" BorderThickness="1">
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding Title}" Foreground="Black" FontWeight="Bold" TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" />
<TextBlock Text="{Binding Content}" Foreground="Black" TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10" />
</StackPanel>
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>