Image renders differently depending on position - wpf

I have an ItemsControl presenting a list of buttons. Each button has an image as it's content (png), but the image looks slightly different for each row.
The below image is magnified version of what I'm seeing:
Here is the xaml:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb1">hello</TextBlock>
<Button Height="{Binding ElementName=tb1, Path=ActualHeight}" Padding="0,-3,-3,-3" BorderBrush="Transparent" Background="Transparent" >
<Image Stretch="Fill" Source="stock_standard_filter.png" Margin="0">
</Image>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I've had a similar issue previously and was able to solve it using SnapsToDevicePixels="True", but that solution is not working this time. I've also tried UseLayoutRounding="True" and RenderOptions.EdgeMode="Aliased"

The height of the button is bound so the image will be stretched to fill the button. Because WPF uses doubles (1/96 inch units) there is bound to be some rounding off. SnapsToDevicePixels and Layout rounding might help when you use them on the StackPanel but as long as you stretch the image it will get blurred.
My best guess is to set "Stretch to None" and experiment with SnapsToDevicePixels and Layout rounding.

Related

Horizontal scrolling a row of ViewBox images in Xaml

I'm working on a UWP Windows 10 app with a XAML UI. One of my pages requires that images fill the height of the window (or screen in tablet mode) and uniformly scale as one long row of images from left to right (going off-screen). I've got this set up perfectly using ViewBoxes for the images inside of a StackPanel set to a Horizontal Orientation like so:
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
The intention is for the images to flow off-screen with a horizontal scroll that allows the user to pan from left to right to see the gallery of images as one long row.
I've tried enabling HorizontalScrollMode on the parent StackPanel like so:
<StackPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollMode="Enabled">
But this did not enable any scrolling at all.
I also tried to wrap everything inside of a ScrollViewer like so:
<ScrollViewer HorizontalScrollMode="Enabled">
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
</ScrollViewer>
But this completly breaks my ViewBox layout by shrinking all the images so they fit within a small portion of the screen and no longer fill the window/tablet height.
I've tried a number of other variations with similar results. Does anyone have some suggestions for solving this? Let me know if you need more info.
You do need a ScrollViewer to enable scrolling, although you might need to set a few properties to make it only scroll horizontally as mentioned in Windows 8 ListView with horizontal item flow
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.ZoomMode="Disabled"
Now the Viewbox is not the most controllable... control. You could try using the
SquareGrid panel from my toolkit instead of the Viewboxes. Maybe simplify it a bit. If that isn't enough - you could add some bindable properties that would update when the size of your window changes and bind the Width and Height of these images to these properties. Note that you can't use ActualWidth or ActualHeight because these don't raise change notifications on size changes.
<GridView x:Name="ImageGridView"
SelectedItem="{x:Bind ViewModel.SelectedLocation, Mode=TwoWay}"
Margin="10,0"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.HorizontalScrollMode="Auto"
Grid.Row="4" Grid.ColumnSpan="5"
ItemsSource="{x:Bind ViewModel.CheckedLocations}"
ItemContainerStyle="{StaticResource PinsGridViewItemStyle}"
ItemTemplate="{StaticResource ImageOverlayGalleryFolderDataTemplate}" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
This is my code to show 1 row of photos. You can adjust by the MaxiumRowsOrColumns. Also note that both HorizontalScrollBarVisibility and HorizontalScrollMode are present to custom as you want to.

Create selectable pushpin in Bing maps (XAML)

This is more of XAML question for silverlight.
<Mobile:DevicePushpinTemplateSelector
m:MapLayer.Position="{Binding Location}"
ZoomLevel="{Binding ZoomLevel, ElementName=MainMap}"
Content="{Binding}">
<Mobile:DevicePushpinTemplateSelector.DotTemplate>
<DataTemplate>
<Ellipse Width="8" Height="8" Stroke="Black" Fill="{Binding IsGPSDataRecent, Converter={StaticResource BoolToGreenRedBrushConverter}}" StrokeThickness="1">
<ToolTipService.ToolTip>
<TextBlock Text="{Binding DisplayId}" />
</ToolTipService.ToolTip>
</Ellipse>
</DataTemplate>
</Mobile:DevicePushpinTemplateSelector.DotTemplate>
<Mobile:DevicePushpinTemplateSelector.NumberedTemplate>
<DataTemplate>
<Border x:Name="border" Background="{Binding IsGPSDataRecent, Converter={StaticResource BoolToGreenRedBrushConverter}}" BorderBrush="Black" BorderThickness="2" Padding="2" Height="20" CornerRadius="8">
<TextBlock VerticalAlignment="Center" Text="{Binding DisplayId}" />
</Border>
</DataTemplate>
</Mobile:DevicePushpinTemplateSelector.NumberedTemplate>
</Mobile:DevicePushpinTemplateSelector>
On XAML above I have 2 different templates based on map zoom level. When it is zoomed out - it shows smaller ellipse, when user zooms closer - I increase size of pushpin.
2 issues:
WIth a lot of pushpins it get's really slow, I beleive it's due to template selection.
I want it to be different. I want to create "IsSelected" property so all pushpins will be the same on all zoom levels but when user clicks on pushpin - it expands in size.
I wonder how do I code "selection" part. I want only one pushpin to be selected at time. I can bind to property and make pushpin parts visible/invisible but I'm not sure how to code "selection" piece. Should it be Button?
When doing a windows phone app I had the issue of many pins causing "lag" the easiest way around that is to only show pins within a certain radius of the centre of the map and remove the others until they come into the radius.
Cheers
Mark

WP7 An Image over the full display

I am developing an application where i want to browse images like native WindowsPhone form.
I have used Pivot control. Everything works, but there is one unwanted thing. The image does not fill all display area. There is a gap on the top of page. I have set margin and padding everywhere where it is possible. And the result is still the same. :(
Here is my XAML code:
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid
x:Name="LayoutRoot"
Background="Transparent"
Margin="0">
<toolkit:PerformanceProgressBar
VerticalAlignment="Top"
HorizontalAlignment="Left"
IsIndeterminate="{Binding IsBusy}"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}"
/>
<controls:Pivot
x:Name="PhotoPivot"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
IsHitTestVisible="True"
ItemsSource="{Binding Photos}"
Margin="0"
Padding="0"
>
<controls:Pivot.HeaderTemplate>
<DataTemplate/>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate >
<controls:PivotItem
x:Name="PhotoPivotItem"
Margin="0"
>
<Image
x:Name="PhotoPicture"
Source="{Binding}"
Stretch="Uniform"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0"
/>
</controls:PivotItem>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
</Grid>
Are you talking about the system tray?
To remove the system tray use the following code:
shell:SystemTray.IsVisible="False"
Update:
I'm not real sure why that extra space is there.
I created a simplified version of your example and the only thing I could think of is to use negative margins. There is probably a better solution that I am just overlooking, but for now you can just use the following:
<controls:PivotItem x:Name="PhotoPivotItem" Margin="0,-10,0,0">
Although, from your posted image, it looks as if you have a bigger gap than I did, so you might need to decrease the margin.

Why might a silverlight ListBox on Windows Phone not allow me scroll all the way down to the bottom?

I have a ListBox in a grid that gets databound when the page loads... pretty straightforward. The problem I'm having is that, after the box is databound, I can scroll... but not all the way to the bottom of the list. It stops an item or two short and won't let me scroll anymore. Here's the listbox XAML:
<Grid x:Name="ContentGrid" Grid.Row="2">
<ListBox x:Name="lbFeed" ItemsSource="{Binding Items}" SelectionChanged="lbFeed_SelectionChanged" VerticalAlignment="Top" Width="480">
<ListBox.ItemTemplate>
<DataTemplate x:Key="MyDataTemplate">
<StackPanel Orientation="Vertical" Width="430">
<TextBlock Text="Some text" TextAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I can post more code, but I'm still getting my feet wet in XAML and I'm not sure what might be causing this. If you need more context, let me know and I'll add it here.
This is a known issue at this stage of ctp release if you happen to have rows that are not fixed height. If this is the case you will likely notice your scrolling is a bit jittery too. Fix the height of your content for now if this is the case for your app and all is resolved.

WPF ListBox DataTemplate and Image Question

I have a ListBox with a StackPanel that contains an image and label.
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Source="{Binding Image}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Image_MouseLeftButtonDown" ToolTip="Click to see this product on adidas.com" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Label Content="{Binding Name}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Label_MouseLeftButtonDown" VerticalAlignment="Bottom" Foreground="White" Style="{StaticResource Gotham-Medium}" FontSize="8pt" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
I want to show a third image (glow.png) behind the currently moused over image. I can't seem to add a second image to the stack panel, and set it's visibility to hidden. I haven't even tackled the mouseover part yet.
Is adding another image inside the stack panel, and then setting it's visibility to visible the right approach on mouseenter, and then swapping back on mouseleave?
Thanks.
You certainly can have one image behind another. Instead of directly adding the image to your StackPanel, add a Grid and then add both images, like this:
<StackPanel Orientation="Vertical">
<Grid>
<Image Source="..." />
<Image Source="{Binding Image}" ... />
</Grid>
<Label Content="{Binding Name}" ... />
</StackPanel>
You might also like to look into Bitmap Effects, using which you can introduce a "glow" effect onto any WPF element.
Edit: Another way to achieve the effect you want (I believe) is to swap out the image's Source property in a trigger. I'm not going to try to write the XAML from memory here, but you could catch the IsMouseOver property for the image itself, and when it switches to True you could set its Source to the "glowing" version of the image.
Another possibility is to add a border to your image, set the color of the borderbrush to whatever you want and the opacity to 0. In your MouseEnter event handler set the opacity to 1.

Resources