Silverlight: Button template with texttrimming cut off - silverlight

I'm replacing the default Button template's ContentPresenter with a TextBlock, so the text can be trimmed when it's too long.
Works fine in WPF. In Silverlight the text gets pushed to one edge and cut off on the left, even when there's space on the right:
Template is nothing special, just replaced the ContentPresenter with the TextBlock:
<Border x:Name="bdrBackground"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
<Rectangle x:Name="rectMouseOverVisualElement"
Opacity="0">
<Rectangle.Fill>
<SolidColorBrush x:Name="rectMouseOverColor"
Color="{StaticResource MouseOverItemBgColor}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="rectPressedVisualElement"
Opacity="0"
Style="{TemplateBinding Tag}"/>
<TextBlock x:Name="textblock"
Text="{TemplateBinding Content}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="rectDisabledVisualElement"
Opacity="0"
Style="{StaticResource RectangleDisabledStyle}"/>
<Rectangle x:Name="rectFocusVisualElement"
Opacity="0"
Style="{StaticResource RectangleFocusStyle}"/>
</Grid>
</ControlTemplate>
How do I fix this?
More info:
With the latest comment about HorizontalAlignment, it's clear that SL's implementation of TextTrimming differs from WPF's. In SL, TextTrimming only really works if the text is aligned left. SL isn't smart enough to align the text the way WPF does. For instance:
WPF button:
SL button with the textblock horizontalalignment = left:
SL button with textblock horizontalalignment = center:

There's an even simpler solution. I set the TextBlock's TextAlignment=Center. Works exactly like in WPF. Thanks for the help!

The problem will be that your HorizontalContentAlignment is set to "Center". Really WordEllipsis only makes sense when the HorizontalAlignment of the TextBlock is set to "Left".
Edit
Getting the desired behaviour try this:-
<Border HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<TextBlock x:Name="textblock"
Text="{TemplateBinding Content}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"
Margin="{TemplateBinding Padding}" />
</Border>

Related

ScrollViewer position in XAML

Is it possible to assign a value to a ScrollViewer in XAML by data-binding? I have a collection of objects (tabs) which are added dynamicaly. Whenever I add a new tab the scrollviewer position should go to the end but it doesn't. I don't want to set the position to be precise, just align the bar position to the very right. Thanks.
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" HorizontalContentAlignment="Right">
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent"/>

Resize container without resizing text controls

I have a Custom Control containing a Canvas placed inside a Viewbox. This allows me to resize the control and everything inside the Canvas scales beautifully.
Much to my annoyance a requirement to stop any scaling of text within the control has reared its head. All other controls (mainly graphics) should scale, but not text. Text should move to the correct place upon resize, but the font should remain the same.
Any ideas how to do this?
After much head scratching I found a relatively simple workaround.
As I'm not going to need to click on any text in the control I've put all graphics inside one canvas with zOrder 1 and all text in another with zorder 0. Then I put them inside a grid so they overlap:
<ControlTemplate TargetType="{x:Type local:ContourPlot}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Viewbox>
<Border BorderBrush="Black" BorderThickness="1">
<Canvas x:Name="cvGraph" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
<Rectangle Canvas.Left="40" Canvas.Top="31" Width="48" Height="41" Fill="AliceBlue"/>
</Canvas>
</Border>
</Viewbox>
<Canvas Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
<Label x:Name="lblTest" Canvas.Left="0" Canvas.Top="10" Content="Label" FontSize="12" />
</Canvas>
</Grid>
</Border>
</ControlTemplate>

How do you style the label for a Silverlight ToggleSwitch?

I am wanting to change the foreground colour of a Silverlight ToggleSwitch, although when i open the object in ExpressionBlend i have no object items to edit.
How is this done? (without rebuilding OR using reflector)?
I am not quite sure what you are doing wrong in Blend, however, you can see the template for the ToggleSwitch if you look at the sourcecode for ToggleSwitch here:
http://silverlight.codeplex.com/SourceControl/changeset/view/61620#1325059
Ignoring the storyboards / VisualStateManager, the control has the following markup:
<Grid x:Name="SwitchRoot" Background="Transparent" Height="95" Width="136">
<Grid x:Name="SwitchTrack" Width="88">
<Grid x:Name="SwitchBottom" Background="{TemplateBinding SwitchForeground}" Height="32">
<Rectangle
x:Name="SwitchBackground"
Fill="{TemplateBinding Background}"
Width="76"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="BackgroundTranslation"/>
</Rectangle.RenderTransform>
</Rectangle>
<Border BorderBrush="{StaticResource PhoneForegroundBrush}" BorderThickness="2">
<Border BorderBrush="{StaticResource PhoneBackgroundBrush}" BorderThickness="4"/>
</Border>
</Grid>
<Border
x:Name="SwitchThumb"
BorderBrush="{StaticResource PhoneBackgroundBrush}"
BorderThickness="4,0"
Margin="-4,0"
Width="28"
Height="36"
HorizontalAlignment="Left">
<Border.RenderTransform>
<TranslateTransform x:Name="ThumbTranslation"/>
</Border.RenderTransform>
<Border
x:Name="ThumbCenter"
BorderBrush="{StaticResource PhoneForegroundBrush}"
BorderThickness="2"
Background="White"/>
</Border>
</Grid>
</Grid>
I would suggest using a different colour where the resource PhoneForegroundBrush is used.
I think you will need to define a new Template for the control and then change your style as you see fit.
You can do this by right clicking on your control and select Edit Template and then create your Edit a Copy. This will create a new Style for you that you can change.

ComboBox ControlTemplate Drop Down Button

I was wondering if anyone had an example of how to style/template a combobox to only show a button at its default initial state. Kind of like the DropDownButton gallery for the ribbon bar. I would just like the user to be able to click a button and have the combobox items listed. When the selection is made it does not save the selected item in the text field because there is no text field only a button. Thanks :)
Here's some sample code:
Note that the ContentPresenter and PART_EditableTextBox have been commented out deliberately and they can be taken off from the template.
Also, you may want to customize the appearance of togglebutton and the popup.
<Window x:Class="HiddenTextComboBox.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="HiddenTextComboBox" TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton x:Name="DropDownToggle"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="-1" HorizontalContentAlignment="Right"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}">
<Path x:Name="BtnArrow" Height="4" Width="8"
Stretch="Uniform" Margin="0,0,4,0" Fill="Black"
Data="F1 M 300,-190L 310,-190L 305,-183L 301,-190 Z " />
</ToggleButton>
<!--<ContentPresenter x:Name="ContentPresenter" Margin="6,2,25,2"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}">
</ContentPresenter>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Focusable="False"
Background="{TemplateBinding Background}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>-->
<Popup x:Name="PART_Popup"
IsOpen="{TemplateBinding IsDropDownOpen}">
<Border x:Name="PopupBorder"
HorizontalAlignment="Stretch" Height="Auto"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Black" Background="White" CornerRadius="3">
<ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<ComboBox Height="23" Width="23" Template="{StaticResource HiddenTextComboBox}">
<ComboBoxItem>First</ComboBoxItem>
<ComboBoxItem>Second</ComboBoxItem>
<ComboBoxItem>Third</ComboBoxItem>
</ComboBox>
</Grid>
</Window>
Code adapted from: Customizing the Appearance of an Existing Control by Creating a ControlTemplate

Windows Themes ButtonChrome Border

I have created my own button based on icrosoft_Windows_Themes2:ButtonChrome. I want to get rid of the default border and i've tried setting it to null or transparent but still i get a white border.
Here's my markup:
<Microsoft_Windows_Themes2:ButtonChrome x:Name="ibAero" Visibility="Collapsed" SnapsToDevicePixels="true" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" RoundCorners="True" Background="{TemplateBinding Background}" BorderBrush="Transparent" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" OverridesDefaultStyle="True">
<Border x:Name="bd" CornerRadius="10" BorderThickness="1" BorderBrush="{Binding ElementName=IB, Path=BorderBrush}">
<StackPanel Orientation="Horizontal" Margin="8,1,5,1">
<TextBlock Text="{Binding ElementName=IB, Path=Text}" Foreground="{Binding ElementName=IB, Path=TextForeground}" Margin="{Binding ElementName=IB, Path=TextMargin}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</Microsoft_Windows_Themes2:ButtonChrome>
EDIT:
Ok. I've changed the markup like this:
<Border x:Name="ibAero" Visibility="Collapsed" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" CornerRadius="3" BorderThickness="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<StackPanel x:Name="ibAeroPanel" Orientation="Horizontal" Margin="8,1,5,1">
<Image Source="{Binding ElementName=IB, Path=Image}" Width="{Binding ElementName=IB, Path=ImageWidth}" Height="{Binding ElementName=IB, Path=ImageHeight}"/>
<TextBlock Text="{Binding ElementName=IB, Path=Text}" Foreground="{Binding ElementName=IB, Path=TextForeground}" Margin="{Binding ElementName=IB, Path=TextMargin}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
How do i set the default style in my usercontrol?
The answer to this problem is posted by Meleak in this link: How to remove ButtonChrome border (when defining the template of a border)?
The reason you get that white border is because it is added IN CODE in the ButtonChrome control. There is NO WAY to achieve the solution to this with templating. The only way to remove the border is write your own version of the control.
I googled this issue and found numerous answers by people offering template "solutions". None of them will ever possibly work as suggested.
Add Meleak's modified ButtonChrome.cs control to your library of customized WPF controls (ComboBox with disabled F4 key being another in my personal inventory) and you are good to go.
I would recommend not including the Button Chrome in your template. It would require extra work if you want to recreate some of the nice effects it provides on mouseover and pressed, but it will get rid of the border.

Resources