cannot draw shape in canvas - c#

I have a canvas in xaml defined as following. However adding a rectangle in it doesn't show any thing.
<lib:DrawingCanvas x:Name="drawingCanvas" Background="White" AllowDrop="True">
<Rectangle Margin="20,20,20,20" Fill="Black" Stroke="White" Width="100" Height="100">
</Rectangle>
</lib:DrawingCanvas>
Can you give me some hints here?
Thanks.

You're not using a Canvas, you're using a "DrawingCanvas", so I can't speak for any differences. But assuming it derives from Canvas:
You need to set the attached properties for the Rectangle. These are Canvas.Left or Canvas.Right, in addition to Canvas.Top or Canvas.Bottom.
For example:
<Rectangle Canvas.Left="50" Canvas.Top="100" Width="100" Height="100" Fill="Black" />

Related

wpf canvas and video control fullscreen

In my WPF program, I want to draw a shape. Then after I press a button, the program plays a video in fullscreen mode. I can't seem to make the video play in fullscreen on the canvas.
my XAML is like below
<Canvas>
<Ellipse Name="face1" Panel.ZIndex="2" Fill="Green" Width="400" Height="400" />
<MediaElement Panel.ZIndex="1000" Name="videoControl1" Stretch="Fill"
Source="C:\Users\videos\carcrash.mp4"
LoadedBehavior="Manual" MediaEnded="videoControl1_MediaEnded">
</MediaElement>
</Canvas>
As you can see, I put the video in front of my shape. as sson as a button is pressed, I then start to play the video. So the video will be in front of the shape. The problem is that the video is very small. How to make it full screen?
Per Dennis Cheng's comment here:
Canvas is a "no-layout" panel so children won't size to parent. Try
Grid if you want children fill or manually Bind to the parent's size
if you must use a Canvas:
<Canvas x:Name="MyCanvas"
Width="300"
Height="300">
<Ellipse Name="face1"
Width="400"
Height="400"
Panel.ZIndex="2"
Fill="Green" />
<MediaElement Name="videoControl1"
Width="{Binding RelativeSource={RelativeSource Self},
Path=Parent.ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Self},
Path=Parent.ActualHeight}"
Panel.ZIndex="1000"
Source="C:\Users\videos\carcrash.mp4" />
</Canvas>
That scales the video's width to that of the containing Canvas, but it remains in proportion to its original dimensions.
If you use a Grid you can achieve the kind of scaling you're aiming for:
<Grid Width="500" Height="500">
<Ellipse Name="face1"
Width="400"
Height="400"
Panel.ZIndex="2"
Fill="Green" />
<MediaElement Name="videoControl1"
Grid.Row="0"
Panel.ZIndex="1000"
Source="D:\Downloads\The.Strain.S01E13.HDTV.x264-LOL.mp4"
Stretch="Fill" />
</Grid>

InkPresenter draw only in transparent area

I have an InkPresenter and this image with a transparent background. I want my strokes to be drawn only in the transparent area and ignore the black border of the shape. How is it possible?
here is an example using WPF, same applies to InkPresenter, you can use InkPresenter.Clip property to define the clip region
<Border BorderBrush="Green"
BorderThickness="1"
Width="200"
Height="200">
<Grid>
<InkCanvas>
<InkCanvas.Clip>
<EllipseGeometry RadiusX="98"
RadiusY="98"
Center="100,100" />
</InkCanvas.Clip>
</InkCanvas>
<Ellipse Stroke="Blue"
StrokeThickness="2" />
</Grid>
</Border>
result
I was able to solve my problem using Opacity Mask:
<InkPresenter.OpacityMask>
<ImageBrush ImageSource="{Binding ImageMask}" />
</InkPresenter.OpacityMask>

Canvas ImageSource not showing image

Here is my xaml:
<StackPanel Height="333">
<Canvas x:Name="imageCanvas"
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased">
<Canvas.Background>
<ImageBrush x:Name="image1"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top">
</ImageBrush>
</Canvas.Background>
</Canvas>
<Canvas x:Name="overlayCanvas">
<Rectangle Name="dummyRectangle" Width="1" Height="2" Fill="Transparent" />
</Canvas>
</StackPanel>
Here is my C# code behind:
void PlayImages()
{
string testImageFolder = "C:\\TestImages";
DirectoryInfo d = new DirectoryInfo(testImageFolder);//Assuming Test is your Folder
FileInfo[] Files = d.GetFiles("*.tif"); //Getting Text files
image1.ImageSource = new BitmapImage(new Uri("C:\\TestImages\\ChanA_0001_0001_0001_0001.tif"));
}
However, when the C# code above executed, nothing happened on UI. I am wondering where should I change to make the image show up? Thanks.
It was the stack panel that causes the problem. I am not sure why, but if some of them are removed, then the image shows up. The xaml with some stack penal removed is like following:
<StackPanel HorizontalAlignment="Left">
<!--Controls:MenuControl/-->
<Controls:ToggleButtonControl Margin="0,0,0,0" Height="43" RenderTransformOrigin="0.5,-0.233" />
</StackPanel>
<Canvas x:Name="imageCanvas"
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased" Margin="0,52,0,0">
<Canvas.Background>
<ImageBrush x:Name="image1"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top"
ImageSource="{Binding Path=Bitmap, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
</ImageBrush>
</Canvas.Background>
</Canvas>
Your imageCanvas always has width and height zero, because you neither add any children, not set its Width or Height explicitly.
Change your XAML to use only one Canvas instead, and optionally (depending on the outer container and the children to be added) set its Width and Height properties:
<Canvas x:Name="overlayCanvas" Height="333" Width="500">
<Canvas.Background>
<ImageBrush x:Name="image1" ... />
</Canvas.Background>
<Rectangle ... />
</Canvas>

Change absolute positioning in Canvas from code

I am creating my own usercontrol where I have a Canvas which will hold Hexagons.
I'm now at the stage where I'm adding the function AddItem, and since I don't want the hexagons to overlap I obviously want to use the Canvas' positioning methods. But how do I access them from "normal" code?
I have a Path object hexagon which holds the hexagon-data and I want to add it to my canvas aka container
So how do I change the positioning from c# code?
I know that in XAML my path looks like this when inside the Canvas (please notice Canvas.Left and Canvas.Top) , you'll have to scroll a bit..
<Canvas x:Name="Container" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<Path d:LayoutOverrides="None" d:LastTangent="0,0" Stroke="White" Fill="#343434" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" Width="50" Height="50" Stretch="Fill" Data="M8.660254,0 L17.320508,5 17.320508,15 8.660254,20 0,15 0,5 8.660254,0 z"/>
<Path d:LayoutOverrides="None" d:LastTangent="0,0" Stroke="White" Fill="#343434" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" Width="50" Height="50" Stretch="Fill" Data="M8.660254,0 L17.320508,5 17.320508,15 8.660254,20 0,15 0,5 8.660254,0 z" Canvas.Left="25" Canvas.Top="37.5"/>
</Canvas>
Use this method
Path myPath = ....; // obtain your path here
Canvas.SetLeft(myPath,25);
Canvas.SetTop(myPath,25);

Centering a large rectangle inside a grid which dimensions are smaller (and ClipToBounds doesn't work)

I'm trying to position a rectangle in the center of a grid with a restricted height, like so:
<Grid ClipToBounds="False">
<Grid Background="LightBlue" Height="10" ClipToBounds="False" Margin="0,27,0,79">
<Rectangle Height="40" Width="20" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False"/>
</Grid>
</Grid>
I've expected it to look like that:
But instead it looks like that:
I know the my child rectangle is bigger and it is understandable that it clips, however, my ClipToBounds have no effect of anything. After reading around, I found that indeed Grid does not respect "ClipToBounds".
I tried to use Canvas, as suggested in the aforementioned article by Dr.Wpf but I can't seem to get it right.
Is there anything I can do to make it look like the 1st picture, without resorting to C# code?
Thanks!
It's a little hard to tell exactly what your requirements are here. You said you tried it witha Canvas, but you can't seem to get it right. What didn't work?
I used this code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestApp.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="175" Height="170" Background="LightGray">
<Grid>
<Canvas Background="LightBlue" Height="10"
Margin="0,27,0,79" VerticalAlignment="Top">
<Rectangle Height="40" Width="20" Fill="Black"
Canvas.Left="66" Canvas.Top="-15" />
</Canvas>
</Grid>
</Window>
and was able to essentially fake what your screenshot looked like. But (as you can tell by the Canvas.Left and Canvas.Top parts of my code) it is sort of hackish. You could get rid of the Canvas.Left by binding to the ActualWidth of the Canvas and using an IValueConverter that converts it to the correct value.
Edit:
After a little further exploration, I came up with a slightly less hackish way of doing it. Though the nesting kind of makes me cringe, the only thing hardcoded is the top margin to get it centered vertically. Again, that can be done with an IValueConverter, but you don't want that. I'm not sure I can get any better than this, unfortunately.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication10.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid Background="LightBlue" Height="10" ClipToBounds="False" Margin="0,27,0,79">
<Canvas>
<Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas}}"
Height="{Binding ActualHeight, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas}}">
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 -40 0 0">
<Rectangle Height="40" Width="20" Fill="Black" ClipToBounds="False"/>
</Canvas>
</Grid>
</Canvas>
</Grid>
</Grid>
</Window>

Categories

Resources