WPF semi transparent button to control MediaElement - c#

I am making WPF application that plays a video.
I use MediaElement, I wish to add Play/Pause button, I want that image button to be in shape of play, and only the image i put on the button will be shown. the rest to be transparent.
e.g: put a play triangle image on a rectangle button will only show the triangle image.

You're going to have to "make your own", fortunately it's not that hard, here is a working example (doesn't handle mouse hovering though):
<Grid Background="Black">
<Button HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}" />
</StackPanel>
</ControlTemplate>
</Button.Template>
<Path Data="M 0,0 L 15,10 L 0,20" Fill="Green"/>
</Button>
</Grid>
The grid is only here to show that only the arrow is actually drawn, and the Path thing is vectorial data to draw a Play button.
It looks like this:

Related

Difficult to get an item tapped - Expand hit area

I have a Image, which I want to get the tap from it (actually the grid that contains it, because it is bigger). But this is not working right, because I have to be really precise when touching the screen to touch the button, otherwise it wont work.
<Grid Grid.Column="0" Tapped="DrawerIcon_Tapped" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Margin="5" x:Name="DrawerIcon" Source="/Assets/but_drawer.png" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image.RenderTransform>
<CompositeTransform ScaleX="0.5" ScaleY="0.5"/>
</Image.RenderTransform>
</Image>
</Grid>
Is there any way to expand the area of an element that gets hit when I tap?
The CompositeTransform only makes the image larger, to make the Hit area larger you have to do the following:
As you did, surround the object (Image) with a Grid
Add the Tapped event to the Grid
The Margin of the Image will determine the hit area; thus making this larger will make the hit area larger (or anything that makes the Grid larger).
Finally, and most annoyingly: Make the Background of the Grid Transparent!
To fix your code, just add Background="Transparent" and you can also increase the Margin to 10 if you like:
<Grid Grid.Column="0" Background="Transparent" Tapped="DrawerIcon_Tapped" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Margin="10" x:Name="DrawerIcon" Source="/Assets/but_drawer.png" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image.RenderTransform>
<CompositeTransform ScaleX="0.5" ScaleY="0.5"/>
</Image.RenderTransform>
</Image>
</Grid
Hope this helps.
I achieve it by making a transparent Rectangle out of every Grid over the object that I want to be tapped (only under the root Grid) and attaching the Tapped event to it. Apparently being under Grids and Stackpanels affect the Tapped event somehow. This is not a real fix, just a workaround. Maybe it's a bug.

Resizable circle button xaml

I'm developping a universal app for Windows in XAML/C# and I can't manage to create a circle button that I can resize. I use an Ellipse with uniform stretch so as to make it circle and a ContentPresenter.
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Stretch="Uniform">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
The problem is a uniform ellipse is automatically aligned top, left, and it's impossible to make it stretch the grid. When I resize the button, the ContentPresenter stays in the center while the ellipse stays in the top left corner. I'd like to be able to resize the button and that the text stays in the center of the circle.
Thanks for help!
You may use a Path with a circular EllipseGeometry:
<ControlTemplate TargetType="Button">
<Grid>
<Path Stretch="Uniform" ...>
<Path.Data>
<EllipseGeometry RadiusX="1" RadiusY="1"/>
</Path.Data>
</Path>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
You would however have to explicitly set the Width or Height of the Button, otherwise it would take up all available space.
I've also found another solution which is to use a ViewBox:
<ControlTemplate TargetType="Button">
<ViewBox>
<Grid>
<Ellipse Stretch="Uniform" Width="50" Height="50">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ViewBox>
</ControlTemplate>
The ViewBox automatically scales everything when resized. You have to set Width and Height, but it's only to set proportions. Very useful when using the user control with both Windows and Windows Phone.
Thanks for your answers!

How to center Content in a Button Template and keep mouse events in empty area

I am using a Button Template to customize the look and feel of my buttons like so:
<ControlTemplate TargetType="Button">
<Border x:Name="Border" CornerRadius="6" BorderThickness="1">
<ContentPresenter Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" ContentSource="Content"/>
</Border>
</ControlTemplate>
I want to center horizontally and vertically the Content, but when I do it the "empty" areas of the Button don't react to the Mouse. When I use Stretch the entire Button behaves alright, but the Content is aligned top-right.
How do I do both?
To make whole area of a Border hit test visible you need to initialise its Background property with some Brush. Can be even Transparent which will have same visual effect as default null.
<Border ... Background="Transparent" />

Mouseover effect on full stretch button

I am using a WPF button mouse ovent to show a specific area in screen and i use the below xaml in code
http://pastebin.com/Rn0CVAHA.
If i remove the Background="Red" property of button control i have to click on exactly the center to show my area on screen .
The screen shot is
How can i make the button control in a way that it works without background color ,but stretch content effect ? Like clicking anywhere on the button area should show the content
I am guessing that this is the offending line in your code
<Border Name="border" Background="Red">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</Border>
The problem is, when you remove the background of the border there is no hittest on the border to react the mouse triggers (IsMouseOver in your case)
The trick is to set the background brush to transparent so that the background can be hit test and will respond to your triggers.
so try changing your Border to
<Border Name="border" Background="Transparent">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</Border>
You can read more about Hit testing on MSDN

How to set Canvas.ZIndex to paint a black panel between the controls?

With the following code I can demonstrate how a black panel with a opacity of 50% is on top of every rectangle:
<Grid>
<Rectangle Fill="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.5" Canvas.ZIndex="1"/>
<Rectangle Fill="Red" Width="200" Height="200" Canvas.ZIndex="0"/>
<Grid>
<Rectangle Fill="Blue" Width="100" Height="100" Canvas.ZIndex="0"/>
<Rectangle Fill="Yellow" Width="50" Height="50" Canvas.ZIndex="1"/>
</Grid>
</Grid>
It looks like this:
I would like to have the yellow rectangle above the black panel, but that seems to be impossible.
I can achieve something close by setting the ZIndex of the Grid containing both the Blue and Yellow rectangles to "1". But this would also raise the blue rectangle above the black, and this is a problem.
<Grid>
<Rectangle Fill="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.5" Canvas.ZIndex="1"/>
<Rectangle Fill="Red" Width="200" Height="200" Canvas.ZIndex="0"/>
<Grid Canvas.ZIndex="1">
<Rectangle Fill="Blue" Width="100" Height="100" Canvas.ZIndex="0"/>
<Rectangle Fill="Yellow" Width="50" Height="50" Canvas.ZIndex="1"/>
</Grid>
</Grid>
How do I get only the yellow rectangle above the black?
In my real application I have user controls instead of the rectangles. I like to make a particular control standing out by having everything else covered by the half-black shade.
Many Thanks,
I don't think you'll be able to achieve this with your current arrangement of controls.
There are two levels of controls here, the "Blue" and "Yellow" controls inside the inner grid and then the "Black" and "Red controls together with the inner grid.
The ZIndex works on controls at the same "level" - so you can ensure that the yellow control is on top of the blue, but then at the higher level these are grouped under the inner grid so are treated as a single unit.
The only way this would work is if all your controls were at the same level. If you included a second semi opaque rectangle in the inner grid you could get the yellow to be on top of that but that might end up making other controls too dark.
One approach might be to not use just a simple black rectangle.
Instead use a Path composed of two rectangles. The first rectangle will cover the whole area and the second would just cover the control to be available.
This creates a large rectangle with a hole in it where your target control can show through and accept input.
The down side is working out the rectangle geometry to add to create the hole but that's fairly straight forward.

Categories

Resources