I have a small UserControl and it needs to know the Background Brush of the control on which it's being rendered.
However, if I look in the Background property of the UserControl it comes back null.
If I call GetValue(UserControl.BackgroundProperty) it also returns null even though up the Visual tree it is definitely being set.
Seems like I must be missing something pretty obvious as it's can't be that hard to figure out the background colour of a control.
It seems to me that your UserControl does not have a background color defined - null means transparent, which is why the parent control's background is visible at all.
It is still the background color of the parent control - the fact that your control does not have its own background color does not mean that it takes the color from the parent control. The "background" of your control will simply show whatever is behind your control.
The background property is not inherited from the parent, you have to set it yourself.
Related
What's the difference between the following two?
Background="{x:Null}"
and
Background="Transparent"
Transparent will create a brush that is initialized to a transparent color, null will set the property to null, this means that the destination property has not an brush attached.
In WPF it's often important to set a brush to an element. If you for example want to track mouse downs in an element, you must set a background. If you don't want to set a solid color (make it opaque), you can use a transparent brush. This can be done with the string value "Transparent".
The difference lies in the manner, how the property will be set. If you assign null for a brush-property, the property will be set really to null. If you set the string "Transparent", the default value-converter that converts string to brushes converts this to the Brushes.Transparent brush.
Short version: {x:Null} sets the destination property to null. "Transparent" sets the destination property to a transparent brush.
Both are setting the local value of the Background property. The former sets it to null and the latter sets it to Brushes.Transparent.
There are a couple of important points to be aware of:
Setting the value to null is not the same as not setting it at all. Since dependency properties obtain their effective value from multiple sources, setting a local value (even if it's null) can take precedence over values potentially sourced from elsewhere, such as a style or animation.
Another option for controlling hit test visibility is the IsHitTestVisible property. This property allows you to control hit test visibility regardless of the brush with which the UIElement is rendered.
{x:Null} will not be clickable, Transparent will.
Also see this.
Elements with Transparent background receive mouse click events when clicking on background, elements with Null do not.
The Transparent brush
Will cause the background's alpha channel to be set to 0 which is 100% transparent
The {x:Null} value
Will cause the background to be set to the default control colour by WPF which is usually White on some properties like DataGrid.RowBackground and Transparent on most of the other properties.
It's a good habit to specify a brush colour since setting a brush to
Null may result in undesired default colours.
I use User Control in panel. When I use white as BackColor of something it becomes transparent automatically even all kind of operation can be done over my app.
What if you try to set BackColor to 'Grey'? does it work?
And could you add screenshoot from User Control properties?
Anyway, I'm having a little difficulty with tab control. When I drag a new tab control onto a form, it appears white, rather than the grey (system colour) I was expecting.
When I look at the properties, its colour is set to web-transparent. Ok, so it should be transparent then (it isn't letting anything behind it show through). Setting the tab control back colour manually back to the system grey kind of works, but the tabs at the top still show as white. I'm assuming I could somehow change their colour as well, but I'm quickly getting into the realms of changing so many values from default, I'm clearly missing something type territory. I've googled every varient of "transparent tab control draws white" as I can, and although I found something to do with windows profiles, this seemed mostly confined to access 2003 using the vb you got access to in access.
I'm looking for any explanation as to:
what I need to do to correctly use transparency with tab controls
what I'm mis-understanding as the purpose of transparency in tab controls
how to easily change all the colours of the appropriate parts of the tab control to not be transparent.
I'm looking at windows forms for an MCTS, so please don't give a "you should use X instead" type answer.
No, getting white is certainly normal. TabControl and TabPage are rendered with theme colors when visual styles are enabled. So that makes the tab page white on machines with the standard Windows theme.
Yes, the default BackColor of Transparent is very unusual. You most certainly will never get actual transparency with that, unless you count seeing the background of the TabControl as transparency. The logic is pretty convoluted, rather than trying to explain it I'll just paste the MSDN explanation:
The default value of the BackColor property is the value of the Control.DefaultBackColor property unless the UseVisualStyleBackColor and Application.RenderWithVisualStyles property values are both true and the Appearance property of the parent TabControl has a value of Normal, in which case the default value of the BackColor property is Transparent. Child controls that you place on the TabPage inherit the BackColor value by default, so this behavior causes the background of the child controls to render with the current visual style.
Changing the value of the BackColor property automatically sets the UseVisualStyleBackColor property to false. If you want the TabPage background to render using visual styles but you want the child controls to inherit a BackColor value that you specify, set the UseVisualStyleBackColor property after you set the BackColor property.
I've got a custom control that inherits from FrameworkElement. It contains a Visual that contains transparent areas. I'm trying to make the entire control area respond to hit tests, but at the moment, when I click on part of the control that displays a transparent area of the Visual, the click passes through to the underlying layer.
Is there a way of making the entire control hit-testable without using a hack?
I'd like to stay away from techniques like painting the background of the Visual white, or adding a Border around the custom control that has the same event handler set.
Thanks in advance!
Simply use a transparent brush and it will respond to hit testing.
For example, if you have null background brush, then hit testing will pass right through.
If you use Brushes.Transparent as a background or fill area, then it will work with hit testing.
using Background or Fill = "{x:Null}" which is the default for some classes like Grid is not the same as Background or Fill = "Transparent". Setting Transparent as the background/fill color should work.
I want to try something different, and am attempting to display an overlay on top of my current WPF GUI that allows the user to still interact with the GUI, but provides a layer of annoyance to let them know that something's up.
My question is really two separate questions:
1. How would you do the overlay?
My first attempt was to use a Rectangle, set the Fill to the appropriate color, and then change the Opacity. But it's not transparent to click-throughs. So I think what I want to do, according to search results, is to create a separate window, set its Background to Transparent, and then set AllowsTransparency to True. While this works, if I want to do something like Background="DarkRed" Opacity="0.2", click-throughs no longer work.
And this leads me to the second part:
2. What's the right way to resize this overlay region if I'm using MVVM?
My main window creates the ViewModel, which creates the Model. The Model is the only thing that knows about whether or not the overlay should be displayed. But the main window obviously is the only thing that knows its size, and the Model never knows about anything above it. Is the only way to achieve this to databind the overlay Window's size to properties in the ViewModel, and then have the ViewModel set these values any time the main Window's size changes?
Anyone have clues on how I can achieve all of these things?
To address part 1: set IsHitTestVisible="False" on your overlay, be it a Rectangle, Border or some other element. This will allow you to make it whatever color and transparency level you want without affecting interaction with the underlying controls.
Part 2: you shouldn't use a separate Window. If you keep the overlay in the main Window you can rely on the layout in your view to automatically handle sizing of the overlay.