Can you set a Canvas the Background of an element in WPF? - wpf

Apologies if this has been asked but I can't find the answer. I have a couple of items (Windows, UserControls and DockPanels) that need dynamic backgrounds.
A Canvas object suits my needs well for the dynamic drawing, however, what I can't figure out is how (or even if) I can set a <Canvas> object as the value of a Background for a control object.
Can this be done and if yes, how?

Yes you can do that.
<Window.Background>
<VisualBrush>
<VisualBrush.Visual>
<Rectangle Width="50" Height="50" Fill="Red"></Rectangle><!-- Replace this with a reference to your Canvas-->
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
Code is referenced from this site there is a lot more that you can do with that background as well. Like set clipping etc ...
Note
Because you haven't specified the language you are developing it, I provided answer in the language I use namely C#, I don't use VB.

Dou you want to set the Background property of a control with the "contents" of a Canvas already populated with elements?
If so, yes; it's possible to accomplish this task creating a Brush from your Canvas. To do it, you need the VisualBrush class. In VB.NET, use something like this:
Dim oBrush As New VisualBrush(myCanvas)
myControl.Background = oBrush
Good luck, good code

Related

How to set WPF default values for properties, if possible?

I am just starting WPF and it is frustrating the hell out of me. It seems that many properties are null by default (at least those I am working on at the moment) and hence when it compiles and run, nothing happens.
Is there a quick way or a standard workflow procedure to set default values for WPF objects?
For example, I put a Canvas and a Button in XAML view, and then went to code view to add an event handler on the Button to Canvas.Children.Add(new Ellipse()) and then nothing happens. Then I thought maybe I should specify the Width and Height. Still nothing happens. Finally, after much struggling I found the Shape.Stroke property.
Then there is no intuitive Ellipse.X and Ellipse.Y to position the Ellipse. Again, took an hour to find the Canvas.SetLeft().
The final straw is when I try to do Canvas.SetLeft(Random.Next(0, (int)Canvas.Width)); It give a runtime error because Canvas.Width is NULL?!!? Goodness...
Sure, WPF gives a lot of features, but seems like a lot of work coming from a Winforms Graphics.DrawEllipse() .. *sweat*
In WPF if you dont explicitly set the Width/Height in xaml the size will be determined by the Elements layout Container, so to access the Width/Height of an Element like this you use the properties ActualWidth/Actualheight, these return the Rendered size of the Element
Example:
Canvas.SetLeft(Random.Next(0, (int)Canvas.ActualWidth));
If you want to create Default values for a Element you can create a style in xaml for that Element
Example:
<Style TargetType="Ellipse">
<Setter Property="Stroke" Value="Black"/>
</Style>
WPF does have a rough learning curve. One of the tougher things is to dispense somewhat with the techniques you may be used to and embrace the WPF-approach. Xaml is the way to go for defining controls and their properties - Xaml is a language whose only real purpose to do declaration well. In essence, think of the Xaml portion of your code as a glorified constructor.
<Window x:Class="TestWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Canvas>
<Ellipse Canvas.Left="50"
Canvas.Top="50"
Width="142"
Height="88"
Fill="Black" />
</Canvas>
</Window>
The declaration above takes advantage of Xaml's nifty syntax for Attached Properties.
You might want to investigate Styles if you find yourself setting a set of common properties on like objects often.

Link Rectangle.Fill to TextBlock.Background

I'm currently migrating from WinForms over to WPF and I'm really struggling with the binding aspects. All i need to do is match the fill property of a rectangle to a textblock.background and keep them in sync. I know I can do this with 'classic' event handlers, but I have 24 textboxes and 24 rectangles, and I'd prefer a more WPF solution. I've toyed with the binding properties but I can't seem to get any type of results since I have no clue with type of binding I even need! Do i need an event, or use a convertor, or possibly a style trigger? Maybe just stick transparent tape on the screen and call it a day?
I know the following doesn't work but this is my level of understanding at this point.
<Rectangle Fill="{Binding Source="textBlock.Background"} />
I've read various articles on databinding but they are all much more advanced, and typically deal with data.
Can someone please shed some light on this helpless n00b!
<TextBlock x:Name="SomeTextBlock" Content="Hi"/>
<Rectangle Fill="{Binding ElementName=SomeTextBlock, Path=Background}"/>
That's the easy way if you are creating them in XAML.

Adding Enumeration Value to Silverlight Attribute/Property

In the <ImageBrush/> element, there are AlignmentX and AlignmentY attributes with values Left/Center/Right and Top/Center/Bottom, respectively.
What I'm wanting to do is set my own value in, for example, AlignmentX either as a value or as another enumeration like AlignmentX="HalfCenter" where HalfLeft equals my own value (halfway between Center and Left). For example, if I have this:
<Rectangle Canvas.Left="0" Stroke="LimeGreen" StrokeThickness="16" Canvas.Top="0"
Width="400" Height="400" >
<Rectangle.Fill>
<ImageBrush ImageSource="newone.jpg"
Stretch="None" AlignmentX="HalfLeft" AlignmentY="Top" />
</Rectangle.Fill>
</Rectangle>
I don't know if this is a Dependency Property, Attached Property or otherwise (don't yet know how to create those). In the helpfile, it says in TileBrush.AlignmentXProperty field: Public Shared ReadOnly AlignmentXProperty As DependencyProperty. Does the ReadOnly word here mean that I can't set this property to a custom property?
If this can't be an override of that property, how can I create my own? I think this is an Attached Property and it could be called something different, like OffsetX and OffsetY that set an ImageBrush to a location inside its parent Shape. I'm getting very confused by the SL documentation on how I would do this though (almost no examples in VB.NET - but even the C# ones aren't all that revealing).
If it is possible, how would I get started on this?
Save yourself the pain and just use a value convertor and even that is going to be a little tricky, since you are going to have to apply a rendertransform or something to react to your enums.
You also could write your own panel which is probably a better idea.
You have a few different problems here to confront, creating the attached property, validating the enum, having the enum do what you want it to do when it is set.
Your also going to have to learn about MeasureOverride and ArrangeOverride
If you just can't help yourself ... Look Here

How to access a WPF control located in a ControlTemplate?

Usually, the WPF controls are declared in the .xaml files and not in the code behind (.xaml.cs files). However, sometimes I need to use some of those controls in code behind in order to manipulate them. How can I get the handle of such a control if it "resides" in the xaml file?
You can use the FindName() method of the ControlTemplate class.
// Finding the grid that is generated by the ControlTemplate of the Button
Grid gridInTemplate = (Grid)myButton1.Template.FindName("grid", myButton1);
I'm unsure about what you're asking, so I'll try and answer both instances that I'm interpreting as your question.
1)
If you want to declare an explicit control, and then edit it directly, all you have to do is set the name property like such:
<Canvas x:Name="myCanvas"/>
You can then access the canvas through the Name as such:
myCanvas.Background = Brushes.Blue;
2)
If you're looking to declare a generic control, and then use it multiple times, you can do it like this:
<Window>
<Window.Resources>
<Ellipse x:Key="myEllipse" Height="10" Width="10">
</Window.Resources>
</Window>
You can then access that predefined control using this syntax in code:
Ellipse tempEllipse = (Ellipse)FindResource("MyEllipse");
If you want to use the Resourse as a template for multiple controls, add x:Shared="false".

Round window playing movie using WPF

Is it possible with WPF to create a window that has the shape of a circle and uses a playing movie as the background?
To make a non-rectangular window, you need to first do three things.
Set Window.WindowStyle to WindowStyle.None
Set Window.AllowsTransparency to True
Set Window.Background to Transparent (or {x:Null})
Now, your window is completely transparent. You can use the other tips in this thread to paint a piece of media onto the window's geometry.
You should just need to throw something like this in your xaml:
<Ellipse Height="80" Width="80">
<Ellipse.Fill>
<VisualBrush TileMode="None">
<VisualBrush.Visual>
<MediaElement Source="myMovie.wmv" />
</VisualBrush.Visual>
</VisualBrush>
</Ellipse.Fill>
</Ellipse>
Actually making the window round would be more difficult. Have a look at this if you want the window to be round, it should help figure that part out.
HTH
Don't use AllowsTransparency, it has very poor performance and a lot of compatibility problems, go to this link for alternatives:
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx
EDIT: there is an example there how to use SetWindowRgn to get rounded corners for a rectangular windows, if you pass an ellipse region instead of a rounded-rect region you will get an elliptic window, it's easy to create a region for any shape you can imagine.
you can have a canvas as your parent container (set to transparent) then add a circle with a media brush as it's background. that should do it. :)

Resources