Image alignment issues in databound Pivot control - layout

I'm using a pivot control and binding my collection of images to it. I'm having a problem with alignment of the photos.
If all the photos are landscape, they align at the top, and I am unable to use the gesture control anywhere below the photo.
If they are a mix of portrait/landscape, the images appear ok, until I rotate the device. Then the portrait images are extremely zoomed in, and the landscape images are located half way down the screen.
I'm new to WP7 development and the layout is still pretty foreign to me. Any assistance would be appreciated. I'm sure someone has to have created a basic photo viewer like this....
<controls:Pivot Name="photoPivot" Loaded="photoPivot_Loaded"
ItemsSource="{Binding _photos}">
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<Grid Height="1" Width="1"/>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<Image VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Source="{Binding photo_link}" />
</DataTemplate>
</controls:Pivot.ItemTemplate>
<controls:Pivot.ItemContainerStyle>
<Style TargetType="controls:PivotItem">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</controls:Pivot.ItemContainerStyle>
</controls:Pivot>

I was able to solve this by removing all height/width definitions from the grid in the data template and the LayoutRoot grid.

Related

Content inside layout panel not scrolling

Say I have a simple Windows 10 UWP app
<Page
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- etc -->
>
<Grid>
<ListView>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
<!-- & many more -->
</ListView>
</Grid>
</Page>
The large number of ListView items causes it to overflow and scroll, as expected:
However, if I need to add another control as a sibling of the ListView, like so (replacing the Grid with a StackPanel for simplicity)
<Page...>
<StackPanel>
<ListView>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
...
</ListView>
<StackPanel>
<TextBlock Text="StackPanel at the bottom"/>
<Button Content="Click me"/>
</StackPanel>
</StackPanel>
</Page>
then the scrollbar disappears and the ListView isn't scrollable anymore. The content just gets clipped / cut off past the bottom of the window.
What's going on here and how can I make it scroll again?
The key to this is the ScrollViewer control. The reason ListViews and GridViews can scroll in the first place is because they have a ScrollViewer built in.
When you place a ListView inside a parent layout panel (e.g. a StackPanel or a Grid row), if the ListView height is greater than the viewport, the parent panel becomes the full height of the ListView. But StackPanel doesn't implement ScrollViewer so it can't scroll, and you end up with a StackPanel extending off the bottom edge of the viewport.
The fix is simple: put the parent layout panel in question inside a ScrollViewer
<Page...>
<ScrollViewer VerticalScrollBarVisibility="Auto"> <!--default is "Visible"-->
<StackPanel>
<ListView>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
<TextBlock Text="Sample text"/>
...
</ListView>
<StackPanel>
<TextBlock Text="StackPanel at the bottom"/>
<Button Content="Click me"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Page>
ScrollViewer API reference - MSDN
Going to add more context to binaryfunt's answer: It depends on the layout logic of the panel you're using!
To note beforehand: ListView internally has it's own ScrollViewer by default.
When laying out it's children, a Grid will typically tell its children they should fit inside the bounds the grid. In the case of the ListView, it's happy to do this, and it's own internal ScrollViewer handles it's children scrolling.
StackPanel on the other hand tells its children they have virtually infinite space to layout in in it's stacking direction - so your ListView has no idea it has to constrain itself to the height of your StackPanel because the StackPanel does not tell it do so and so the ListView never needs to use it's own ScrollViewer as it thinks it has infinite space.
Now, put a StackPanel in a ScrollViewer by itself doesn't help - if you put that ScrollViewer inside a StackPanel you have the same problem as the ListView does - it thinks it has infinite space and so never needs to scroll it's content. But, put the ScrollViewer in a Grid and the grid will give the ScrollViewer a defined size to layout in, and so anything inside the ScrollViewer will now scroll if it get's too big.
Put a ListView inside this StackPanel inside this ScrollViewer? The ListView still thinks it has infinite space and so never needs to use its own scroller, BUT it's also disables and virtualization and performance enhancements the ListView would normally have, as they rely on it's interal ScrollViewer actually being put a too use.
(binaryfunt's XAML answer will work.)

The button is not visible

I have a UWP application, I have added a button but when I debug the application, I can't see the button. If I add a texblock or textBox I can see them, but not the button.
I have set IsEnabled to true and visibility to visible but I am not able to solve the problem.
Also I have tried to click in the place where it should be the button but nothing happens.
This happens when I debug in local machine and when I debug in a emulator of windows phone 10.
Thank you so much.
EDIT: the axml code
<Page
x:Class="SqliteEF7UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SqliteEF7UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<Button x:Name="GetVideos" IsEnabled="True" Visibility="Visible" Background="Aquamarine" Content="Buscar Videos" HorizontalAlignment="Left" Margin="120,98,0,510" VerticalAlignment="Stretch" Click="button_Click"/>
<TextBlock x:Name="textBlock" Foreground="BlueViolet" HorizontalAlignment="Left" Margin="101,59,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="34" Width="132"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="213,59,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"/>
</Grid>
</Page>
The margin you set for the Button is too aggressive. The object is now "squeezed". For example set Margin to "120,98,0,200" (or simply "120,98") instead of "120,98,0,510" and it should be visible.
BTW using hardcoded margins to setup the user interface is probably not a good idea. Use for example the Grid with columns and rows instead of margins.

Simple animations of TextBlock and Grid controls

My goal is to do simple animations (es fadeIn, fadeOut) of a TextBlock for example.
How can I do it? I searched some explanation but I found them very very complicated, talking about scenarios, ecc. I would know if it can be more simple, or if someone can give me a simple explanation of the procedure.
Thanks in advance.
This code should give you an idea how to do it (the duration could be reduced if it's too slow for you)
This is the Xaml:
<Grid Grid.Row="1">
<Grid.Resources>
<Storyboard x:Name="FadeOutStoryboard">
<!-- This animation will animate the value of the Canvas.Left property of the rectangle Scenario1Rectangle to 300. -->
<DoubleAnimation
Storyboard.TargetName="txtToFade"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1"
To="0"
/>
</Storyboard>
<Storyboard x:Name="FadeInStoryboard">
<!-- This animation will animate the value of the Canvas.Left property of the rectangle Scenario1Rectangle to 300. -->
<DoubleAnimation
Storyboard.TargetName="txtToFade"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1"
To="1"
/>
</Storyboard>
</Grid.Resources>
<StackPanel>
<TextBox Name="txtToFade"></TextBox>
</StackPanel>
</Grid>
And in the code behind this is how you execute the storyboards:-
FadeOutStoryboard->Begin();
or
FadeInStoryboard->Begin();
You can use the VisualStateManager to control the animations based on events (such as mouse over etc).
Have you tried the animation sample at this location?
http://code.msdn.microsoft.com/windowsapps/Animations-f758de70

How to get the text in list box to be right aligned?

My ListBox is databound to 2 fields. The first is left aligned which is fine, the problem is with the second one which has to be right aligned. I tried using TextAlignment ="Right" and also HorizontalAlignment="Right", none of them worked.
Here is a sample code:
<ListBox x:Name="_listBox">
<ListBox.DataTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,4,8,0">
<TextBlock Text="{Binding Path=ContainerNumber}" />
<TextBlock TextAlignment="Right" Text="{Binding Path=Content}"/>
</StackPanel>
</DataTemplate>
</ListBox.DataTemplate>
Any ideas?
Add to the StackPanel markup:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,4,8,0">
This problem is that the StackPanel isn't using all the width available because it is by default aligned Left horizontally.
EDIT: Alternatively you need to style ListBoxItems:
<ListBox.Resources>
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.Resources>
Hope this helps.

Silverlight / WPF Custom Control Template Help

I'm hoping to create a control that I call an "AutoCompleteListBox". If you've ever used hotmail to send an e-mail the way the to: address line works is what I wish to create. You have what looks like an input box and as you type you get a dropdown of matching objects. Once you select an object (contact) it is added into the input box as a rectangular object. Multiple objects can be added this way and the input box acts like a wrap panel. You can delete objects by backspacing them or clicking the x button on each.
My approach was to begin by subclassing ItemsControl. I've started to write its control template which is basically a wrap panel that I want to show the bound items + a text box. I don't know how to get both the bound items and the textbox to be in the same wrap panel. Here's what I have:
<Style TargetType="ctrl:AutoCompleteListBox">
<Setter Property="Width" Value="200"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:AutoCompleteListBox">
<ScrollViewer x:Name="RootScrollViewer" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Padding="0" Background="{TemplateBinding Background}">
<toolkit:WrapPanel IsItemsHost="True">
<!--Items Bound To ItemSource Go Here-->
<TextBox x:Name="txtInput"/>
</toolkit:WrapPanel>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I don't know how to express what I want. I know you can use an "ItemsPresenter" in the control template which does show the bound items but then how can I add my textbox into the same panel as the bound items?
I'd greatly appreciate any help. Is this the right way to even go about it? Thanks very much.
Subclassing the items control is a good start, but I think the controltemplate should be setup a bit different. The Silverlight toolkit contains an excellent autocomplete box that you can use for this exact purpose. Combine this with a separate items control and you should have something that can be styled to look exactly like the live mail "To" field.
<ControlTemplate>
<toolkit:WrapPanel>
<ItemsControl ItemsSource="{TemplateBinding Items}">
<ItemsControl.ItemsPanel>
<StackPanel Orientation="Horizontal"/>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<!-- Add data template for the previously added items here -->
</ItemsControl.ItemTemplate>
</ItemsControl>
<toolkit:AutoCompleteBox ItemsSource="{TemplateBinding AutoCompleteItems}" />
</toolkit:WrapPanel>
</ControlTemplate>

Resources