Load custom polygon as button image in WPF - c#

I have made a small cross icon using a polygon as following:
<Viewbox Margin="28,-22,-28,22">
<Polygon
Points="300, 200 325,200 325,250 375,250 375,275 325,275 325,325 300,325 300,275 250,275 250,250 300,250 300,200" Height="513" Width="595">
<Polygon.Fill>
<SolidColorBrush Color="#666666" Opacity="100"/>
</Polygon.Fill>
<Polygon.RenderTransform>
<RotateTransform CenterX="313" CenterY="237" Angle="45" />
</Polygon.RenderTransform>
</Polygon>
</Viewbox>
Now I want this polygon to be loaded into my button. How can I do this?

Put that inside Button.Content:
<Button ...>
<Viewbox ...>
</Viewbox>
</Button>
Don't forget to remove ViewBox.Margin (make Button big enough) or make it negative.

Related

How to overflow a shadow from a fixed Height container

I found here that the DropShadows can't overflow over component with a fixed Height.
I tried to add somme ClipToBounds="False" in every containers but it doesn't seems to work.
you will see the problem if you create a new project with this code :
<Window .... >
<StackPanel x:Name="Sp2" Margin="20" Height="47" ClipToBounds="False">
<Rectangle Height="40" Fill="Purple" Margin="4" ClipToBounds="False">
<Rectangle.Effect>
<DropShadowEffect Opacity=".4" BlurRadius="13" ShadowDepth="4" Direction="288"/>
</Rectangle.Effect>
</Rectangle>
</StackPanel>
</Window>
Here is a screenshot of the problem :
On the left that's what i want, a shadow overflowing on a fixed height component, and on the right that's what i have.
As I work in a team and I'm developping every UI components for our application and I'd like other people of my team not to have to pay attention to these kind of details. How can we avoid this behavior, and if we can't what would be the guidelines to avoid this clipping effect ?
You can override GetLayoutClip() to stop most things clipping.
As explained here.
http://drwpf.com/blog/2007/12/28/cliptoboundsmaybe/
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace wpf_99
{
public class NoClipStackPanel : StackPanel
{
protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
return ClipToBounds ? base.GetLayoutClip(layoutSlotSize) : null;
}
}
}
Markup
<Grid>
<local:NoClipStackPanel x:Name="Sp2" Margin="20" Height="47" ClipToBounds="False">
<Rectangle Height="40" Fill="Purple" Margin="4" ClipToBounds="False">
<Rectangle.Effect>
<DropShadowEffect Opacity=".4" BlurRadius="13" ShadowDepth="4" Direction="288"/>
</Rectangle.Effect>
</Rectangle>
</local:NoClipStackPanel>
</Grid>
One possibility to solve this issue is similar to solution of another problem, when trying to apply effects to control containing text and text become blurred. The idea is to detach effect, by applying it to something else, while ensuring that visually it looks like effect was applied to where you need it.
In your case you can do something like this:
<Grid>
<Rectangle Width="{Binding ActualWidth, ElementName=rect}"
Height="{Binding ActualHeight, ElementName=rect}"
Fill="Green">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="30" />
</Rectangle.Effect>
</Rectangle>
<StackPanel Margin="20" Height="47">
<Rectangle x:Name="rect" Height="40" Fill="Purple" Margin="4">
<!-- remove effect from here -->
</Rectangle>
</StackPanel>
</Grid>
The effect is not anymore on nested rectangle, but on some element (I've used Rectangle) which is added below StackPanel (since its transparent) in visual tree. If you do it like this than shadow can now extend itself to whole grid (which takes whole window size).

WPF rectangle anchor

I have a canvas and I set a background image to it. I have some rectangles within the canvas. When the form gets resized, the background image gets strechted but I also want the rectangles to get to the new positions. Any help?
<Window x:Class="abc.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jas="clr-namespace:foo"
Title="foo" Width="1200" Height="800" >
<jas:DragCanvas x:Name="jasCanvas" >
<jas:DragCanvas.Background>
<DrawingBrush Stretch="None" TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute">
<!-- a drawing of 4 checkerboard tiles -->
<DrawingBrush.Drawing>
<DrawingGroup>
<!-- checkerboard background -->
<!--<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,20,20" />
</GeometryDrawing.Geometry>
</GeometryDrawing>-->
<!-- two checkerboard foreground tiles -->
<!--<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,10,10" />
<RectangleGeometry Rect="10,10,10,10" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>-->
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</jas:DragCanvas.Background>
<TextBlock x:Name="m_resultText" FontSize="16" Canvas.Left="10" Canvas.Top="10"
jas:DragCanvas.CanBeDragged="False"
FontWeight="Bold"
Background="Black"/>
<Rectangle x:Name="m_redRect" Width="40" Height="120" Canvas.Left="100" Canvas.Top="50" Stroke="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
StrokeThickness="1" >
<Rectangle.Fill>
<!--<SolidColorBrush Color="#99FF0000"/>-->
<ImageBrush ImageSource="Media/yacht.png" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_redRectRotate" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="m_greenRect" Width="40" Height="120" Canvas.Left="247" Canvas.Top="113" Stroke="Gray"
StrokeThickness="1"
>
<Rectangle.Fill>
<!--<SolidColorBrush Color="#9900FF00" />-->
<ImageBrush ImageSource="Media/yacht.png"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_greenRectRotate" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="m_greenRect2" Width="40" Height="120" Canvas.Left="338" Canvas.Top="113" Stroke="Gray"
StrokeThickness="1"
>
<Rectangle.Fill>
<!--<SolidColorBrush Color="#9900FF00" />-->
<ImageBrush ImageSource="Media/yacht.png"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_greenRectRotate2" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Button Content="Button" Canvas.Left="464" Canvas.Top="10" Width="75" Click="Button_Click" x:Name="buton" jas:DragCanvas.CanBeDragged="false"/>
</jas:DragCanvas>
</Window>
here is the background image set :
ImageBrush ib = new ImageBrush();
ib.ImageSource = new BitmapImage(new Uri(#"Media\foo.jpg", UriKind.Relative));
jasCanvas.Background = ib;
There is a very simple solution that you can use... just put your Canvas inside a ViewBox control. From the linked page on MSDN, the ViewBox Defines a content decorator that can stretch and scale a single child to fill the available space:
<ViewBox Stretch="Fill">
<jas:DragCanvas x:Name="jasCanvas">
...
</jas:DragCanvas>
</ViewBox>
If it doesn't work straight out of the box, then just experiment with the Stretch and StretchDirection properties.
I'm not sure about your jas namespace, but there is no layout system support in standard Canvas panel. So if you want something placed inside canvas to move and resize automatically due to parent canvas position change you have to create some code for this behavior manually.
Modify your XAML code like this:
<jas:DragCanvas x:Name="jasCanvas" SizeChanged="jasCanvas_SizeChanged">
And then in your code behind file:
private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
var deltaWidth = (e.NewSize.Width - e.PreviousSize.Width);
m_redRect.Width += deltaWidth;
// and so on
}

ViewportControl and Images - how to avoid endless scrolling

I am coding a kind of map (for a very simple game) which is (for now) an image.
I want the user to be able to scroll the image around and resize it.
I tried a lot around, and currently i am using the ViewportControl, and the XAML looks more or less like the following (see below).
I works as it does all i need - BUT the image itself can be scrolled within the ViewportControll without any boundaries. As a result the image scrolls away.
Question: is there any way to prevent the Viewportcontroll to scroll the image out of a specified region?
<ViewportControl x:Name="viewport" Height="600" Width="440">
<Canvas x:Name="ParentCanvas" Background="Red" MaxHeight="600" MaxWidth="440">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" Stretch="UniformToFill" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="-200" Canvas.Top="-300" Width="1320" Height="1800">
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>
After testing around i have a solution for my problem.
The most important part is to add the Bounds-tag to the ViewportControl as you can see below.
The scrolling is then handled by the ViewportControl itself. The pinch-gesture must be done manually, but it is possible, because the events will reach the correct UI-Element (here: the image).
In the example below, i used the Windows Phone Toolkit to handle the event more easily.
<ViewportControl x:Name="viewportCtrl" ScrollViewer.VerticalScrollBarVisibility="Visible" VerticalContentAlignment="Center" Bounds="0,0,1320,1800">
<Canvas x:Name="ParentCanvas" Background="Red" Height="1000" Width="800">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" >
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<Canvas x:Name="BlueCanvas" Top="100" Left="200" Background="Blue" Height="180" Width="180"></Canvas>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>

Image cropping windows phone

I want to crop an image in wp7 such that only some part of it appears in an imagebox (or just the 'image' control). I used image.clip, but it actually retains the whole image, and just whitens the 'to-be-cropped' portion. How can i crop the image so that the cropped image is the resultant image?
Note: I am looking for a way in xaml
This is working for me just fine with Light and Dark themes. I'm showing a square image inside an ellipse clip and adding a border around it; it's not showing through.
<Grid>
<Ellipse
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="78"
Height="78"
StrokeThickness="5"
Stroke=""/>
<Image
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="UniformToFill"
Source="{Binding MediumPhotoUrl}"
Width="64"
Height="64" >
<Image.Clip>
<EllipseGeometry RadiusX="32" RadiusY="32" Center="32,32"/>
</Image.Clip>
</Image>
</Grid>
Are you sure you're doing clip correctly?
If you know the size of the initial image, you can calculate the required transforms, for example:
<Image Width="100" Height="100">
<Image.Clip>
<!-- Image after clipping takes only a small area in the center -->
<RectangleGeometry Rect="25,25,50,50"/>
</Image.Clip>
<Image.RenderTransform>
<!-- Transforms Rect(25,25,50,50) into Rect(0,0,100,100) -->
<TransformGroup>
<TranslateTransform X="-25" Y="-25"/>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
I don't know a way of doing it automatically (without code behind).

xaml ScrollViewer, blurred border - Windows Store App

Is it somehow possible to have somekind of a blurred border when scrolling? For better understanding I added a picture of what I want to acchieve.
The restriction that I have is, that underneath the ScrollViewer I have got a background Image. Thus, I cant just use a filled Rectangle with white to transparent gradient at the left side of the ScrollViewer.
Since WinRT dropped support for OpacityMask and I'm not sure if you'd want to set it with an Alpha channel. With that said though, there's pretty much always a work around. So what if you just utilize the natural z-order instead and fake it? Something like this;
<!-- Grid as Container -->
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<!-- example backgrounds, like images, just for the concept example. -->
<StackPanel Orientation="Horizontal">
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
</StackPanel>
</ScrollViewer>
<!-- An adhoc gradient overlay to just float over the ScrollViewer itself.
Then using Margin to fit it to the shape of the Scrollviewer and still
allow hit visibility to the scrollbar etc. -->
<Rectangle Width="50" HorizontalAlignment="Left" Margin="1,1,0,20">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0.1,0.5">
<GradientStop Color="White" Offset="0.3"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
Of course you'll probably want to tweak some values like the Rectangle Margin in the example to make it look exactly right with your own setup, but the concept should be there and is an option. Hope this helps.

Categories