Resize container without resizing text controls - wpf

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>

Related

How to add a border line without shadow effect in wpf

the above tree view is looking with shadow effect on top left and left. I need a single thick line .
my xaml is
Margin="0,0,0,2" BorderBrush="Black" BorderThickness="1"
I need a single line but not a shodow. Can you please help me how to do it ?
One way to do it is to create simple Template for your TreeView like so:
<TreeView BorderBrush="Black" BorderThickness="1" Background="Beige">
<TreeView.Template>
<ControlTemplate TargetType="{x:Type TreeView}">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</TreeView.Template>
</TreeView>
You can try this to get rid of treeview border and apply your own border:
<Border BorderThickness="1" BorderBrush="Black">
<TreeView BorderBrush="Transparent" BorderThickness="0"
</TreeView>
</Border>

Round a arbitrary content control

I have an Esri ArcGis map control which I want to round around the edges. I am also using Prism4.0/MEF and SL4.
I tried to place it in a border, but that doesn't work (the Esri control is loaded into the MapRegion, in another module):
<Border Grid.Row="2"
Margin="2"
CornerRadius="25">
<ContentControl
prism:RegionManager.RegionName="MapRegion"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch">
</ContentControl>
</Border>
UPDATE: Looks like this is not possible. This isn't really a bug with the Map itself, but it kind of is. The Map uses a Canvas inside the Grid "RootElement". This Canvas holds the images for the map. When using a Canvas, it doesn't respect the bounds it's been given. You can reproduce the bug with the following XAML
<Border BorderBrush="Red" BorderThickness="2" CornerRadius="25">
<Grid>
<Grid>
<Canvas>
<Image Source="/Images/MyPicture.png"/>
</Canvas>
</Grid>
</Grid>
</Border>
The best approach is going to be to set an explicit style for the map. With this style any map that is used will have the rounded corners
<Style TargetType="esri:Map">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="esri:Map">
<Border CornerRadius="25" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<Grid x:Name="RootElement" Height="Auto" Width="Auto"/>
<Rectangle x:Name="ZoomBox" Fill="#55FFFFFF" Stroke="Red" StrokeThickness="2" Visibility="Collapsed"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

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.

masking in WPF template (opacitymask reversed)

I am currently redoing a groupBox's template.
I would like the header to have rounded corner on top and "inverted" rounded corner at the bottom:
I managed the above template quite easily by rounding the top corners of the content part and putting the content on top of a "background" container having the darkest color as background.
BUT...
my specifications require that the content's background (lightgray on the picture) might be transparent (i.e.: it should be possible to see right through the content part without having to loose the header's background color). And this is where I'm stuck...
I could easily split this control into two rows of a grid, one for the header, the other for the content and have pretty rounded corner at the top, but I would not be able to get those "inverted" rounded corner at the header's bottom, would I?
so I would be really glad if somebody could either:
point me to a solution (involving whatever dirty trick)
confirm that what I want to do is impossible
thanks in advance
You could use a Path to obtain what you want, a Path that describes the whole dark gray area of your header. You can look at the examples here and figure out the data for your Path.
I figured it out, using the path option submitted by Andrei.
for those interested, here is the final template (using a cornerRadius of 3):
<Border x:Name="Border"
CornerRadius="3"
Background="{TemplateBinding local:MyGroupBox.ContentBackground}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3"/>
<ColumnDefinition/>
<ColumnDefinition Width="3"/>
</Grid.ColumnDefinitions>
<Border x:Name="HeaderBorder"
Grid.Row="0"
Grid.ColumnSpan="3"
CornerRadius="3,3,0,0"
Background="{TemplateBinding Background}" />
<ContentPresenter Grid.Row="0"
Grid.ColumnSpan="3"
Margin="6"
ContentSource="Header"
RecognizesAccessKey="True"
HorizontalAlignment="Center"/>
<Path x:Name="LeftCorner"
Grid.Row="1"
Grid.Column="0"
Stretch="Fill"
Data="M0,0 L3,0 C1.3431457,0 0,1.3431457 0,3 L0,0 z"
Fill="{TemplateBinding Background}"/>
<Path x:Name="RightCorner"
Grid.Row="1"
Grid.Column="2"
Stretch="Fill"
Data="M0,0 L3,0 3,3 C3,1.3431457 1.6568543,0 0,0 z"
Fill="{TemplateBinding Background}"/>
</Grid>
</Border>
Perhaps that top area contains two borders?
<Border Background="Gray"
Height="{TemplateBinding CornerRadius,
Converter={StaticResource ExtractHeight}}">
<Border Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius,
Converter={StaticResource UseTop}}" />
</Border>
Your lower area would have something similar in a Border with just the bottom corners in the CornerRadius property.

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