Semi-transparent background only in controls - wpf

I wonder if it's possible to make a new template (e.g. for a button), that have semi-transparent background? I can set the Background property and then choose my Opacity, but here lies the problem... When I set opacity of the background, each element added as a content of an element with set Opacity will be transparent, too. How to avoid it?

How about this? It's just a simple version. You will have to add the triggers etc by yourself.
<Style x:TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:TargetType="Button">
<Border BorderBrush="{TemplateBinding BorderBrush}">
<Grid>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Border Background="{TemplateBinding Background}"/>
</Grid>
</Border>
<ControlTemplate/>
</Setter.Value>
<Setter/>
</Style>
Now you can assign any background brush you want without influencing the content.

Related

Round the corners of a button in Window.Resources WPF

I am very new to WPF. I've familiarized myself with ControlTemplate, ContentPresenter, and some other pieces, but I am struggling to create a button with rounded corners as defined from Window.Resources (or potentially a separate style file).
Anyways, when I add this to a <Button/> tag, I get a button with rounded corners:
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Button.Resources>
However, when I try to include it up in the Window.Resources the button will not apply the border style:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Rectangle Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}"/>
<Border CornerRadius="5"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
This doesn't look right to me, but I guess I don't know where to add the specification of CornerRadius such that it will apply to the button. I did see this post, How to create/make rounded corner buttons in WPF? but it's a little over my head. I just want to round all the buttons in my application!
The Border in your ControlTemplate is not visible, because you have neither set its Background, nor its BorderBrush.
You could have something like shown below. Note however that with a simple ControlTemplate like this a Button loses all the visualizations of its states, like focused, mouse-over, pressed etc.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="5">
<ContentPresenter/>
</Border>
</ControlTemplate>
You may instead just declare a default Button Style (i.e. a Style resource without x:Key) that applies your original Border Style like this:
<Style TargetType="Button">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Style.Resources>
</Style>

Setting ContentControl's background color in XAML

For the life of me I cant seem to figure out this simple task of setting the ContentControl's background color:
<ContentControl x:Name="Content03"
Width="130"
Height="130"
Canvas.Top="50"
Canvas.Left="400"
Background="Yellow">
<Ellipse Fill="YellowGreen" IsHitTestVisible="True">
</Ellipse>
</ContentControl>
Also tried doing this using styles but still doesnt work ;(
A ContentControl has no visual prescence in itself, but is a container for a child control. Setting some properties on this control (like fontsize etc) is usually only a way of having those properties propagate down the visual tree, so they van be picked up by child controls (those that support it).
The best thing to do is this:
<ContentControl x:Name="Content03"
Width="130"
Height="130"
Canvas.Top="50"
Canvas.Left="400">
<Grid Background="Yellow">
<Ellipse Fill="YellowGreen" IsHitTestVisible="True">
</Ellipse>
</Grid>
</ContentControl>
If you don't have to stick with ContentControl I suggest using Border instead.
When I've had the same problem, Border had the same Child property that I needed to only have one child and to easily switch it via code with a different object. Border uses Properties like Background correctly. Those Properties also work, if Child is null.
<Border x:Name = "Content03"
Width = "130"
Height = "130"
Canvas.Top = "50"
Canvas.Left = "400"
Background = "Yellow">
<Ellipse
Fill = "YellowGreen"
IsHitTestVisible = "True">
</Ellipse>
</Border>
I know this is old but you could also change the template of the ContentControl in the style. That can be overkill for some things, but in this case it's really just wrapping a ContentPresenter in a Border and some template binding:
<Style TargetType="ContentControl" x:Key="StPortal">
<Setter Property="Background" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This gives you the ability to set background, etc. properties that borders have, AND gives the ability to set things like font family and size that ContentControl has and Border doesn't...

Dropshadow UserControl

I think doing the following is probably pretty common:
<Grid>
<Border>
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
</Border>
<SomeControl/>
</Grid>
Ok, I did that without the aid of the ide which I am admittedly lost without so forgive me if I forgot something but I think you get the point.
My question is, would it be possible to create a UserControl that would allow me to do this instead:
<DropShadowBorder>
<SomeControl/>
</DropShadowBorder>
If so, please do tell how.
EDIT: Just in case it's not immediately obvious, the point here is that I would usually put a border around my control but when I want to use a drop shadow I can't because I only want the border to have a drop shadow and not everything in it. So instead I have to create the border separately in the same grid space, but this is annoying because when I adjust margins and such on my control I have to go duplicate those changes on the border each time.
You can't do a user control (user control cannot have a content). You will have to create a custom control. I suggest you to create a custom control that derives from ContentControl.
The code of the custom control (default code !):
public class DropShadowBorder : ContentControl
{
static DropShadowBorder()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DropShadowBorder), new FrameworkPropertyMetadata(typeof(DropShadowBorder)));
}
}
Then define a default style for your control (in generic.xaml)
<Style TargetType="{x:Type local:DropShadowBorder}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DropShadowBorder}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
</Border>
<ContentPresenter Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Setting TextTrimming (CharacterEllipsis) in DataGrid's Cell

I would like to apply TextTrimming property (CharacterEllipsis) to the text in WPF DataGrid cells.
I applied custom DataGridCell template as in this answer (code below) and it works well, except for the Hyperlink columns like the first one in the picture), which now are empty.
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="3" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding Text}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I can see the difference in both column types in visual tree:
but don't understand how I can use this information to apply TextTrimming to TextBlock's columns of both type. Thanks for your time ;)
I finally ended up with the following solution (more like a workaround, but it works fine):
1) I assigned an x:Key to the style in question and applied it as a CellStyle to all DataGridTextColumns that should have their contents trimmed and ellipsisized whenever they don't fit
2) To apply ellipsis trimming in DataGridHyperlinkColumns, in App.xaml I added the following style:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
</Style>
which will apply to all implicitly generated TextBlocks (as described in CodeNaked's answer). This might seem a bit overkill, but I can't see much difference in rendering performance and Hyperlinks are now trimmed as expected.

Silverlight 4 - Mousewheel stops scrolling ScrollViewer when over contained RichTextBox

I have a Silverlight 4 out-of-browser application with a ScrollViewer that has several RichTextBoxes inside. The RichTextBoxes are only used for displaying text, and are never edited and never scroll.
However when the mouse is hovering over a RichTextBox the mousewheel event seems to not reach the ScrollViewer. Is there any way to overcome this limitation?
The reason a readonly RichTextBox doesn't scroll is because the default template for RichTextBox uses a ScrollViewer instead of a ContentControl. So to solve the problem, you need to create your own template for RichTextBox.
What I did was to create a copy of the RichTextBox template in Blend, and strip it down for the readonly case. This removes about 90% of the template. The following style/template remains:
<Style TargetType="c:RichTextBlock">
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="RootElement">
<Border x:Name="Border" CornerRadius="0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
>
<ContentControl x:Name="ContentElement" IsTabStop="False" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use this style/template for your readonly RichTextBox'es, and you should be good to go.
Goood luck,
Jim McCurdy
Face to Face Software and YinYangMoney

Resources