Setting Opacity on parent <Grid /> makes children indepedently transparent - windows

I have a list of items, and when an item becomes "complete", it's opacity is set to 0.4 to fade it away. Also when an item is completed, the icon gets an orange-yellow completion overlay.
.
The markup for this is something similar to
<Grid Opacity="{x:Bind IsCompleted, Converter={StaticResource BooleanNumberConverter}, ConverterParameter=0.4|1}">
[...]
<Canvas>
<Image />
<Rectangle
Visibility="{x:Bind IsCompleted, Converter={StaticResource BooleanVisibilityConverter}}"
Canvas.Top="0" Canvas.Left="0"
Width="48"
StrokeThickness="2"
Opacity="1"
Height="48" Stroke="#ffC19954" />
<Polygon
Visibility="{x:Bind IsCompleted, Converter={StaticResource BooleanVisibilityConverter}}"
Opacity="1"
Canvas.Top="23" Canvas.Left="23" Points="0,25 25,25, 25,0" Fill="#ffC19954" />
</Canvas>
[...]
</Grid>
The problem I'm having is that it appears the opacity is applied individually to each descendant, so the orange completion triangle appears semi-tranparent on top of the icon, and you can see the icon underneath. You can also see this where the triangle overlaps the border.
Instead, the desired behaviour is that the triangle should be completely opaque and the grid as a whole should be semi-transparent, as it behaves in CSS:
opacity applies to the element as a whole, including its contents, even though the value is not inherited by child elements. Thus, the element and its children all have the same opacity relative to the element's background, even if they have different opacities relative to one another.
It should look like
(note how the white icon is not visible through the orange triangle)
Is there a way to change how opacity is composited and rendered to achieve this? Very soon the app's background will be slightly transparent, so I need a solution that will work with that as well.

You can get around this by simply doing the inverse.
Put a mask grid, above the item, set a solid color to the grid, set it to 0 opacity, and simply increase its opacity when you want the content behind to fade.
<Grid Name="BaseGrid">
<Canvas>
<Image />
[...]
</Canvas>
<Grid Name="MaskGrid" Background="Gainsboro" Opacity="0.2"/>
</Grid>

Related

How to make a label to take entire Frame element space

I have a grid with Frame elements as cells. Within some frame elements, there's label elements. The problem is the label stretches only as much as its content.
My goal is to make labels take the entire space of its parent elements(Frames).
I tried setting the VerticalOptions and HorizontalOptions properties to "StartAndExpand" and also "FillAndExpand" to no avail
<Grid>
<Frame Grid.Row="0" Grid.Column="0">
<Label Text="Hello" />
</Frame>
...
</Grid>
Thank you!
EDIT: To clarify, I want to stretch label itself but not its text.
As Frame has a default padding, simply set it manually like below.
<Frame padding="0">
<....>
</Frame>
Plus, sometimes label with long text not behave correctly inside the Frame,
and one workaround is to wrap the Label with a StackLayout.

Overflow Hidden Image inside border

I have this code
<Border BorderBrush="White" BorderThickness="2" Margin="5" Grid.Row="0"
Tap="ContentControl_Tap" Background="Transparent">
<Image x:Name="ImgTop" ManipulationDelta="Top_ManipulationDelta" Stretch="Uniform" >
</Border>
I cannot set width of the image (i can have different images, and images can have different size... I cannot crop the image)
I need to "hide" the excess of the image... the problem is that when image is too big the excess go ON the border, not under.... Any idea how can i solve the problem?
Thanx
I realize this question was from awhile ago, but I just ran into a similar issue and I think I've got a solution.
I have a Grid that is 340x162 and I'm planning to create an image rotator of some sort inside of it. I'm considering animating the image into a negative top margin to have the image pan out slightly before it goes to the next slide. However, when the image moves up it goes outside the border.
My solution is to create a clip on the Border, as follows:
<Border Width="340" Height="162">
<Border.Clip>
<RectangleGeometry Rect="0,0,340,162" />
</Border.Clip>
<Image Name="Image1" Source="Assets/my-image.jpg" Stretch="UniformToFill" Margin="0 -20 0 0"/>
</Border>
That clips the border starting at the point 0,0 and it uses a rectangle that is 340x162, which is the same size as the border. As soon as I added that, the negative margin on the image didn't pull the image out of the border.
Hope that helps someone...

Putting together image pan, zoom and rotation (C#, XAML)

I want to display images that the user has provided. These images are likely to be larger than the screen resolution (so need zoom and pan capability) plus the image may not be orientated correctly for the screen (so need to be able to rotate).
Implementing pan and zoom seems to be somewhat straightforward:
<ScrollViewer HorizontalSnapPointsType="None" HorizontalScrollBarVisibility="Auto" VerticalSnapPointsType="None" ZoomSnapPointsType="None" IsHorizontalRailEnabled="False" IsVerticalRailEnabled="False" ManipulationMode="All" VerticalScrollBarVisibility="Auto">
<Image x:Name="pannableImage" Source="{Binding FullSizedImage}" AutomationProperties.Name="{Binding Title}" />
</ScrollViewer>
This works well and meets my needs, although I would like to be able to set the initial zoom factor so that if the image is larger than the screen, the zoom factor is set so that it fills the screen and if the image isn't larger than the screen, the zoom factor is set so that the image is shown at its full size, i.e. not zoomed in.
However, I'm struggling to get rotation to work acceptably. I've tried this:
<ScrollViewer HorizontalSnapPointsType="None" HorizontalScrollBarVisibility="Auto" VerticalSnapPointsType="None" ZoomSnapPointsType="None" IsHorizontalRailEnabled="False" IsVerticalRailEnabled="False" ManipulationMode="All" VerticalScrollBarVisibility="Auto">
<Image x:Name="pannableImage" Source="{Binding FullSizedImage}" AutomationProperties.Name="{Binding Title}" >
<Image.Projection>
<PlaneProjection RotationZ="{Binding ImageRotation}"/>
</Image.Projection>
</Image>
</ScrollViewer>
Although this does rotate the image, the problem is that the ScrollViewer then gets the scrolling wrong. I've also tried putting the Projection onto the ScrollViewer instead of the Image and that is even worse.
Putting the project onto the image seems to make the most sense since the ScrollViewer should then get the dimensions of the projected image but that doesn't quite seem to be the case.
What am I misunderstanding here, please?
Thanks.
Philip
The solution was to use a RenderTransform instead of a Projection:
<Image x:Name="pannableImage" Source="{Binding FullSizedImage}" ManipulationMode="All" Loaded="pannableImage_Loaded" IsDoubleTapEnabled="False" IsHitTestVisible="False" IsHoldingEnabled="False" IsRightTapEnabled="False" IsTapEnabled="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" LayoutUpdated="pannableImage_LayoutUpdated">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="Scale" />
<RotateTransform x:Name="Rotate" />
<TranslateTransform x:Name="Translate" />
</TransformGroup>
</Image.RenderTransform>
</Image>

how to update canavas layout after rotation in WP7?

I have a main page with 2 canvas like this:
<Canvas Name="main_canvas_color" Width="480" Height="800" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
<Canvas Name="main_canvas_image" Width="480" Height="800" HorizontalAlignment="Center" VerticalAlignment="Center">
</Canvas>
</Canvas>
the first one is filled by color the other one is filled by image. In PhoneApplicationPage_OrientationChanged event a swap width and height for both canvas. If i rotate a screen, it works fine, everything positioned correctly. If I add a Border element as a children to main_canvas_image and then rotate screen, main_canvas_image is not updated in a right way, it is shifted toward top right corner. If I open any another page and then go back after that, main_canvas_image is updated properly. So it seems that i have to force layout update, but i don't know how to do that. I tried UpdateLayout(); inside PhoneApplicationPage_OrientationChanged event, but it does not work. How can I update canvas layout in a right way?
Why bother ? The phone automatically adjust the size when you change the orientation. No reason to write code for it yourself.

Why won't controls stretch in WP7?

Here is a simple XAML snippet:
<Grid x:Name="ContentGrid">
<ContentControl Background="Yellow" VerticalAlignment="Stretch"></ContentControl>
</Grid>
In WPF, the content control stretches the entire height of the grid.
In WP7 however, the content control does not stretch.
Why?
Avoid using ContentControl directly.
If you use something which inherits from it, such as a button, then, in a grid, as per your example, you'll automatically get horizontal and vertical stretching.
This will creat a button with a yellow background which fills the screen:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Button Background="Yellow" />
</Grid>
However, if you just wanted a yellow background to your grid - which is all your sample would do - you could just set the background property on the grid itself.
I fixed this by defining my own template:
<ContentControl><ContentControl.Template><ControlTemplate><ContentPresenter/> ...
Not sure why it fixes it but it works....

Resources