Border fail to size to Textblock - c#

In an attempt to go around the problem described in this other question: Segoe UI Symbol smiley is sometimes colorful, sometimes not (WP8.1 + XAML), I tried the following: wrapping my Textblock with a Border element with rounded-corners (high CornerRadius). This way I can change the background color of the border and it looks pretty much as if the smiley had a background color itself... almost.
There is still a small gotcha I cannot wrap my head around: the height of the TextBlock seems to be out of my control. The "Segoe UI Symbol" (smiley) I want to display acts as if it had some kind of padding that prevented the border to fit the icon exactly. I end up with some kind of oval shape around my round smiley... not quite what I had in mind.
I stripped the XAML to its bare essence and played with it in a new blank app (just paste this in a new app, you should see exactly the screenshot below):
<Grid>
<Border Background="Red" Grid.Column="0"
CornerRadius="50" BorderThickness="0"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="😠"
FontFamily="Segoe UI Symbol" FontSize="50"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
This gives you that:
Any idea what I can tweak there?

The problem is that the text (emoticon) has not the same height and width. You can do a custom fix by applying a custom style to the textbox and change its padding until you achieve the result you want. It's not a dynamic solution but if the size of the icon is standard this solution i think will work.
First of all create a new style:
<phone:PhoneApplicationPage.Resources>
<Style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
<Setter Property="Padding" Value="10,0,10,3"/>
</Style>
</phone:PhoneApplicationPage.Resources>
Then apply it to the TextBlock
<Grid>
<Border Background="Red" Grid.Column="0"
CornerRadius="50" BorderThickness="0"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="😠"
FontFamily="Segoe UI Symbol" FontSize="50"
HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource CustomTextBlockStyle}" />
</Border>
</Grid>
The result:
If you want something like this:
Try to play around with padding and margin too
<Style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="-2,-13,-2,-9"/>
<Setter Property="Padding" Value="0,0,0,0"/>
</Style>

Related

Horizontal alignment in control seems to be ignored on all but the last item

I have a custom radio button based on togglebutton:
<Style TargetType="{x:Type local:ToolbarRadioButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="60"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<iconPacks:PackIconModern Kind="{Binding TbIcon, RelativeSource={RelativeSource AncestorType=RadioButton}}"
Height="30" Width="35" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding TbText, RelativeSource={RelativeSource AncestorType=RadioButton}}" FontSize="12"
HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I use this control to create four toggle/radio buttons. I've horizontal centered the items in datatemplate, but I end up with this:
Forecast and its icon seem to be centered, but the others are partially left-aligned. They all use the same control so shouldn't they all be centered?
EDITS FOR CLARITY:
It doesn't matter which order I put them in, Forecast is always the one that's aligned correctly.
There is no whitespace in the text nor is there whitespace in the images and all images are sized according to the control defined above. Here's the implementation portion in case it's useful, though they're all the exact same:
<StackPanel Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
<customs:ToolbarRadioButton TbText="Day" TbIcon="CalendarDay" GroupName="calViewType" x:Name="dayOnOff"/>
<customs:ToolbarRadioButton TbText="Week" TbIcon="CalendarWeek" GroupName="calViewType" x:Name="weekOnOff"/>
<customs:ToolbarRadioButton TbText="Month" TbIcon="CalendarMonth" GroupName="calViewType" x:Name="monthOnOff" IsChecked="True"/>
<customs:ToolbarRadioButton TbText="Forecast" TbIcon="PeopleMultiple" GroupName="calViewType" x:Name="forecastOnOff"/>
</StackPanel>
For future readers: I figured out the answer by digging into the documentation on Button. There is a property on buttons called HorizontalContentAlignment (and vertical, of course) that apparently needs to be set to align the visual content. You can't set the HorizontalAlignment property of the item that is the content explicitly; apparently, the button wants to do that for you.

Mahapps's DropDownButton customize appearence

I am using DropDownButton control of Mahapps.Metro components pack.
I want to highlight the whole line in ContextMenu (this is a part of this control).
XAML
<controls:DropDownButton x:Name="ddbPlaylist" Grid.Column="1" BorderThickness="0" ArrowBrush="{x:Null}" ItemsSource="{Binding PlaylistVM}"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Bottom" Grid.Row="0">
<controls:DropDownButton.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</controls:DropDownButton.ItemContainerStyle>
<controls:DropDownButton.Content>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" Style="{StaticResource DetailsTextStyle}" VerticalAlignment="Bottom"/>
</controls:DropDownButton.Content>
</controls:DropDownButton>
As the MenuItems contains left and the right margin, reserved in order to show icon and glyph. I have found a solution for ContextMenu System.Windows.Controls.MenuItem without icon area but can not understand how to apply it in my case. Becouse ContextMenu lies in very depths of DropDownButton template, i ca not find a way to change it's style.

WPF: Style ToolTip with Image

Is it possible to create a style for ToolTip that would place an image next to the Item on which the tool tip resides and then show the tool tip text when the user hovers over the image? Something like this:
Currently I am doing a StackPanel to add the image with the tool tip like so:
<StackPanel Orientation="Horizontal">
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0">
</CheckBox>
<Image Source="/DelphiaLibrary;Component/Resources/info.ico"
ToolTip="Check if you want to re-upload ...."/>
</StackPanel>
EDIT
Just to clarify, I am looking for a way to style ToolTip such that if I define ToolTip on any object (i.e., Button, CheckBox, etc.) the info image is shown and the tool tip text is placed on this info image.
I would like to be able to do something like this and still get the same as the stack panel above:
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0"
ToolTip="Blah blah blah..."
Style="{StaticResource ToolTipImageStyle}">
</CheckBox>
And be able to apply this ToolTipImageStyle to any control (i.e., Button, CheckBox, TextBox, etc.). If that isn't possible can I style an individual control and just create different styles for different controls (one for buttons, another for TextBlock, etc.)?
This should do it. I couldn't figure out the color so just change that.
Source 1
Source 2
<Image Source="/DelphiaLibrary;Component/Resources/info.ico" Width="25" Height="25">
<Image.ToolTip>
<ToolTip Background="LightBlue">
<TextBlock Width="200" TextWrapping="WrapWithOverflow">
Check if you want to re-upload table foxpro.hrpersnl from the source. <LineBreak />
Leave unchecked to use existing data that has been previously uplaoded.
</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>
Update 1:
Source 1
In the App.xaml add this:
<Application.Resources>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}" >
<TextBox Background="LightBlue" Width="200" TextWrapping="WrapWithOverflow" Text="{TemplateBinding ToolTip.Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Then in your XAML file change to:
Note: This will work with all object's tool tips.
<Image Source="Images/MenuImageZoomOut.png" Width="25" Height="25"
ToolTip="Check if you want to re-upload table foxpro.hrpersnl from the source. Leave unchecked to use existing data that has been previously uplaoded." />
The image:
If this doesn't work, try this: Source

WPF toolkit bar charts, setting the column width programmatically

I am trying to programmatically set the width of the column series in a WPF toolkit bar chart. Below is the existing code. But I am unable to set the width using ColumnDataPoint.WidthProperty.
Any suggestions would be of great help!
Style columnStyleRed = new Style(typeof(ColumnDataPoint));
columnStyleRed.BasedOn = this.Resources["CustomStyle"] as Style;
Setter setBackgroundRed = new Setter(ColumnDataPoint.BackgroundProperty, new SolidColorBrush(Colors.DarkRed));
Setter setWidth = new Setter(ColumnDataPoint.WidthProperty, 20);
columnStyleRed.Setters.Add(setBackgroundRed);
Thanks!
I tried the same without any luck.
ATM, I'm looking at OxyPlot, which seems to play much nicer than the toolkit.
This seems to work :
<oxy:ColumnSeries ... ItemsSource="{Binding Items}" ... ColumnWidth="4"/>
It can also be done from the code if you need it.
Ugly fix, I have the same problem, but My displays are going to be static as far as column numbers. I hard coded the margins in the template, that increased there widths.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DVC:ColumnDataPoint">
<Grid>
<Rectangle
Fill="{TemplateBinding Background}"
Stroke="Black"
StrokeThickness="1"
Margin="0,0,-20,0"/>
<Grid
Background="Transparent"
Margin="0 -20 0 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<TextBlock
HorizontalAlignment="Center"
Background="Yellow"
Text="{TemplateBinding FormattedDependentValue}"
FontWeight="Bold"
FontSize="8"
Margin="5,5,-20,2"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

Blurry text in WPF even with ClearTypeHinting enabled?

I have a grid with this template and styles in WPF/XAML:
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter x:Name="CellContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RenderOptions.ClearTypeHint="Enabled" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="CellContent" Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter TargetName="CellContent" Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter TargetName="CellContent" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
The DropShadowEffect I have when you select a grid row, seems to make the text rendering blurry (gray anti-aliasing):
When I remove the drop shadow effect, it looks clear because it now uses ClearType and not gray sub-pixel anti-aliasing:
I have tried applying RenderOptions.ClearTypeHint="Enabled" to the ContentPresenter as seen above, but it does not help.
How do I force WPF to render the text that gets displayed with drop shadow effect to retain Cleartype anti-aliasing, instead of that ugly blurry gray sub-pixel anti-aliasing?
Some believe it's blurry because of the drop shadow -- this is not true. It's blurry only because ClearType is not used. This is how it looks like in Firefox when shadow AND ClearType:
ClearType enabled text is colorful -- but that blurry text is not, because it does not use ClearType -- it uses gray sub-pixel anti-aliasing and that's not how ClearType works: http://en.wikipedia.org/wiki/ClearType
The question is: how do I enable ClearType for this text?
How about setting TextOptions.TextFormattingMode to Display as well as RenderOptions.BitmapScalingMode to NearestNeighbor? The latter is new in WPF 3.5 SP1 and I normally use it to remove the blur. :)
<TextBlock Text="Hello world" TextOptions.TextFormattingMode="Display"
RenderOptions.BitmapScalingMode="NearestNeighbor"
HorizontalAlignment="Center" TextWrapping="Wrap"
VerticalAlignment="Center" Foreground="White" FontFamily="Microsoft Sans Serif">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black"
RenderingBias="Quality"/>
</TextBlock.Effect>
</TextBlock>
Below is how it looks like.
And this is how it looks like in FireFox.
The DropShadowEffect object cannot work with ClearType. This is stated on the MSDN page How to: Create Text with a Shadow:
These shadow effects do not go through the Windows Presentation
Foundation (WPF) text rendering pipeline. As a result, ClearType is
disabled when using these effects.
After all, DropShadowEffect is a bitmap effect, not a text effect.
To achieve a similar result without using an effect, you can render the text twice, once slightly offset from the other:
<Grid>
<TextBlock Text="Here is some sample text" Foreground="Black" Margin="1,1,0,0"/>
<TextBlock Text="Here is some sample text" Foreground="White"/>
</Grid>
This yields the desired result:
You could also encapsulate this into a control (called ShadowTextBlock, perhaps) so that you don't have to go repeating yourself everywhere.
What about combining the two ideas. Draw the text with DropShadowEffect, and overlay it with the same text drawn without effect, like shown in the third line here:
Still not perfect, and i find it a little bold. But perhaps something you could live with. The XAML:
<StackPanel Background="LightSteelBlue" RenderOptions.ClearTypeHint="Enabled" SnapsToDevicePixels="True" >
<Grid Margin="5">
<TextBlock Foreground="Black" Text="Here is some sample text" Margin="1"/>
<TextBlock Foreground="White" Text="Here is some sample text"/>
</Grid>
<TextBlock Margin="5" Foreground="White" Text="Here is some sample text">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality"/>
</TextBlock.Effect>
</TextBlock>
<Grid Margin="5">
<TextBlock Foreground="White" Text="Here is some sample text">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality"/>
</TextBlock.Effect>
</TextBlock>
<TextBlock Foreground="White" Text="Here is some sample text"/>
</Grid>
</StackPanel>
The reason this doesn't work, and the reason you won't be able to get it to work, has to do with ClearType's sensitivity to what it's rendering on top of. For ClearType to look correct it essentially needs to do per-component alpha blending. That is, a separate alpha value for red, green, and blue (normally alpha applies to all 3). What this means is that ClearType absolutely must be rendered into a bitmap that is already opaque (all alpha values are 255) (you'll notice that window title bars still have ClearType, but they use some super secret tricks to do this).
The next step to understanding this is that WPF effects first render into an off-screen bitmap, and are then combined with what's beneath (in this case, solid white, or maybe blue if it's selected).
So, the text is first rendered into a clear, transparent bitmap. Since it has no idea what will eventually be below it, it must render using grayscale instead of ClearType. Then, the effect is applied to that bitmap. Then the bitmap is drawn to where you expect it to be on-screen, and there's no chance of getting ClearType even if it's on top of a solid color with no transparency.
As a possible workaround, try using 2 copies of the text. First, apply the effect to the "lower" version of the text (by "lower" I mean it should have a lower Z-index value, and that is the case if it is "first" in the XAML). Then, draw normal text on top of it (which will get ClearType). I think this will work but I haven't tried it, and you'll probably have to experiment until you get the desired visual outcome.
I know this post is old but if anyone is having problems with blurry text, a border drop shadow could be the culprit. I have custom panels with a drop shadow and only when the panels were placed side by side was the text blurry. I found the answer from this Why everything in WPF is blurry? post. The solution for me was ecreif's answer and not the accepted answer. Add this to your control
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="NearestNeighbor"
SnapsToDevicePixels="True
RenderOptions.ClearTypeHint="Enabled"

Categories

Resources