Retrieve the Default Selection Opacity - wpf

Text selection in WPF (text boxes etc.) looks different from that of other UI toolkits, as WPF uses a semi-transparent overlay over the text for its selection rectangle.
The SystemColors class provides the color used for that rectangle in the HighlightColor property (and the other properties related to it). However, that color is fully opaque. Hence, the color has to be used as a reduced opacity.
Documentation pages on TextBoxBase.SelectionOpacity, PasswordBox.SelectionOpacity and on FlowDocumentPageViewer.SelectionOpacity suggest:
The default is 0.4.
On the other hand, this blogpost says:
SelectionOpacity (...) defaults to a value of .6.
Whatever that default value is, is there any way to retrieve the selection opacity to be used with SystemColors.HighlightColor from the environment, rather than hardcoding an arbitrary value (which may not even be the best choice for non-standard highlight colors)?

No, and yes.. There is no SystemColors.HighlightOpacity - but there should be.
The SelectionOpacity default property value is hardcoded to 0.4 in WPF: http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Controls/Primitives/TextBoxBase.cs,9716201433499854
I don't exactly know how this can differ(0.6 as you said), it seems to be hardcoded as 0.4 in every .NET that supports it(4.0, 4.5).
If you want to actually query the default value of SelectionOpacityProperty, you can do so:
var prop = TextBoxBase.SelectionOpacityProperty;
var defValue = (double) prop.DefaultMetadata.DefaultValue; // 0.4

Related

Is it possible to change colour palette on a per window / user control basis?

I am wondering if with the Telerik WPF library it is possible to change colour palette on a per window / usercontrol basis.
For clarity, I am not refering to basic Foreground or Background colours, I am interested in changing colours for certain visual states such mouse over or focused which is not possible to simple change on a control.
In the docs there is a sample for changing a colour palette such as FluentPalette.Palette.BasicColor = (Color)ColorConverter.ConvertFromString("#33000000");.
But this will have an effect on the whole app UI, whereas I am aiming to change the palette on a per window basis.
The way it looks to me, the only option would be to copy the specific theme for each variant (if that's possible at all) each with its colour palette tweaks for each window, which is of course overkill.
Any ideas?

Leaflet: How to control opacity of Layer Groups?

Does some expert know how to change the opacity of each tilemap of a Layer Group by using a HTML-slider input?
For example: I've got several tilemaps, which could be switched by using Lealet's Layercontrol button, like here: Leaflet Layer Groups.
When using the opacity-slider I want to dim each tilemap, not just one being actually active. For example: I'm dimming map1 to 0.5
Then switching to map2, its opacity should already also be 0.5. And when changing the opacity of map2 to 0.8 with the slider and switching back to map1, map1 should already have opacity 0.8 again (not the former adjusted value of 0.5)
I know how to implement the slider control and how to change the opacity of a single tilemap by using the command
nameOfMaplayer.setOpacity(opacityValue);
But I don't have an idea how to reference using Leaflet's methods to the Pane/Grid Layer/array of all tilemaps to change the map's pane opacity instead of the opacity of each indivdual tilemaps simultaniously.
I think in the end I found a satisfying answer myself:
If we want to change the opacity of the tilePane (= basemap-layers AND overlaymap-layers):
map.getPane('tilePane').style.opacity = 0.5;
But this has the disadvantage that also the Overlay-tilemaps get dimmed which I wanted to avoid.
My prefered method is to change just the opacity of the active basemap-layer. Since Leaflet doesn't support getting the active basemap Layer, you'll have to use the "Activelayers"-Plugin and use its methods:
ctrLayer = L.control.activeLayers(baseMaps, overlayMaps, {position: 'topright'}).addTo(map);
.....
tilemapLayer = ctrLayer.getActiveBaseLayer().layer;
tilemapLayer.setOpacity(actualOpacityValue);
Each time you change the basemap, you have to run the later 2 commands to change the new basemap's oppacity to the actual used opacity value.

WPF control default size

When defining custom resource themes for a wpf application, I can set width / height etc... How can I find the default value for these properties (i.e. the values used in the controls provided in the framework) ?
WPF controls don't generally contain any kind of default size. One of the main functional points of WPF is that everything resizes dynamically unless you specify a size.
If you do want to measure the amount of space a control would like to have if given infinite space, you can create it, call Measure on it with a Size of +infinity, +infinity, and then check DesiredSize. For most controls, this will give you the minimum size the control wants. If you give a fixed size in Measure, some controls will return that they want all that space as they size to their container (e.g., Grid, TextBox, Button...). Some controls size only to their content, so they'll tell you they want no space (e.g., StackPanel).
So you have to ask yourself why you would even think of the concept of a default size in WPF when almost all controls are made so that they either size to their content or size to their container depending on how they are set up. The main thing you'd want to measure is text, and you can do that with the trick above for items like TextBlock or images.
Edit: to query any DependencyProperty for a default value, use the property's metadata:
double defaultWidth = double.NaN;
PropertyMetadata widthMeta = TextBlock.WidthProperty.DefaultMetadata;
if (widthMeta != null && widthMeta.DefaultValue is double)
defaultWidth = widthDefault.DefaultValue;
To Reset a DependencyProperty to its default value, call DependencyObject's ClearValue:
MyTextBlock.ClearValue(TextBlock.WidthProperty);
To check for a locally set value:
if (MyTextBlock.ReadLocalValue(TtextBlock.WidthProperty) != DependencyProperty.UnsetValue)
The default width and height for FrameworkElements is Double.NaN. If you don't specify a different size then WPF controls will automatically size themselves to try and fit their content, their containers or both.

How to resize multiple WPF controls when the text size changes?

What's the correct pattern to resize controls when a font size changes?
For example, I used the WPF designer to make a form, and placed UI elements from the toolbox. Late in the game I got the requirement that the font size of every UI element needs to be configurable, so now I'm thinking there has to be a better way to resize controls when the font size changes. Right now I'm doing alot of code behind calculations on Margin properties.
For such cases I usually place my control inside Grids and StackPanels, this way font size won't affect the layout, everything will be stretchable.
Never place controls on the Window using absolute coordinates.
Make sure your Height and Width on the controls are set to Auto.
When you use the designer/toolbox to add controls it usually provides a static height/width. If you type the tag in the XAML editor you get the control default which is usually Auto.
You'll notice the black diamond in the property window next to the attributes that are changed from their default value. You can right click and choose reset value to clear the attribute from your XAML and see what the default value is.

WPF Custom Draw Multiple Progress Bar

In processing a group of items, I wanted to display a unified image of the status of the group, so I essentially made a Grid of a number of progressbars with transparent backgrounds and various colored foregrounds all at the same cell.
I'm running into some transparency artifacts (purple bar is actually purple under the green, and sometimes it draws over the top, etc) and it just seems a bit wasteful. So, I decided to make my own, but now I've got a bit of paralysis on how to do it. Do I use the DrawingContext in FrameworkElement's OnRender, or is there something simpler? Is there a set of general rules when it comes to making your own control?
I pondered switching to a pie chart since those are easy to come by, but its high time I did something not off-the-shelf.
Thanks!
I'm not quite sure how you intend the progressbar to combine different progresses, but if say the furthest along progress is at the bottom of the z-index and the least along progress is at the top, then I'd do something on the lines of this:
1) I would probably create a user control for this new progresbar.
2) It would have a property called NumberOfProgresses, that is tied with an array containing status of said progresses.
3) Each progress would be represented by a Border item (or perhaps something more suitable up the visual tree), because it's a simple wpf control with a background property. The background property would be set to nice a looking progress style and the progress color can be bound in the style to say the border's borderbrush property. Making it easy to set the color of the progress.
4) The user control would have a method UpdateProgress which takes the percentage value and the index of the progress in the array as parameters.
5) As progresses are updated you can either, just calculate the appropriate width (user control actual width * percentage) for the border and play around with the Z index to get it displayed at the top/bottom, or stack the borders horizontaly, set the least along progress as first, then for the rest of the progresses you'd have to substract previous progresses lengths to get the same effect.
This way there would be no transparency induced artifacts and no OnRender()...
Mind you, in WPF there should be no reason to mess with OnRender this and OnRender that, like it was required in WinForms with OnPaint.
Just set up the elements via code to get the look you want, and let WPF do it's rendering ;)
I can imagine one problem with this user control though. You'd have to provide feedback to the user as to which color belongs to which progress. But that would probably take you back to square one, meaning it's better/simpler to just display multiple progressbars.

Resources