Change font family programmatically in wpf - c#

I'm creating a WPF application.
I have created a folder in my solution and I have some fonts in it.
How can I change programmatically the TextBlock FontFamily ?

XAML
<TextBlock
Name="textBlock"
Background="AntiqueWhite"
Foreground="Navy"
FontFamily="Century Gothic"
FontSize="12"
FontStretch="UltraExpanded"
FontStyle="Italic"
FontWeight="UltraBold"
LineHeight="Auto"
Padding="5,10,5,10"
TextAlignment="Center"
TextWrapping="Wrap"
Typography.NumeralStyle="OldStyle"
Typography.SlashedZero="True"
>
<Run Background="LightGreen">Text run 1.</Run>
<LineBreak/><Run Background="LightBlue">Text run 2.</Run>
<LineBreak/><Run Background="LightYellow">Text run 3.</Run>
</TextBlock>
Code behind
TextBlock textBlock = new TextBlock(new Run("A bit of text content..."));
textBlock.Background = Brushes.AntiqueWhite;
textBlock.Foreground = Brushes.Navy;
textBlock.FontFamily = new FontFamily("Century Gothic");
textBlock.FontSize = 12;
textBlock.FontStretch = FontStretches.UltraExpanded;
textBlock.FontStyle = FontStyles.Italic;
textBlock.FontWeight = FontWeights.UltraBold;
textBlock.LineHeight = Double.NaN;
textBlock.Padding = new Thickness(5, 10, 5, 10);
textBlock.TextAlignment = TextAlignment.Center;
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Typography.NumeralStyle = FontNumeralStyle.OldStyle;
textBlock.Typography.SlashedZero = true;
if you want to load a custom font
controlID.FontFamily = new FontFamily("file:///Font
Full Path");

Take the Control e.g. a TextBlock and set its style with
Style style = new Style(typeof(TextBlock));
Then add a setter using a resource as follows
style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, this.FindResource("NameOfResource")));
Finally set the style to the control...
myTextBlock.Style = style;

Related

Set mapcontrol's children topmost

I'm adding a stackpanel to a mapcontrol. like below
But some of the points added before are on the top of my stackpanel. How to set my stackpanel topmost?
XAML:
<Grid x:Name="gridMain">
<maps:MapControl
x:Name="mapControl"
ZoomInteractionMode="GestureAndControl"
TiltInteractionMode="GestureAndControl"
RotateInteractionMode="GestureAndControl">
<!--ZoomLevel="{x:Bind ViewModel.ZoomLevel, Mode=OneWay}"
Center="{x:Bind ViewModel.Center, Mode=OneWay}"-->
<maps:MapItemsControl x:Name="MapItems">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<Grid Tapped="MagPoint_Tapped" maps:MapControl.NormalizedAnchorPoint="{Binding NormalizedAnchorPoint}" maps:MapControl.Location="{Binding Location}">
<Ellipse Canvas.ZIndex="0" Width="{Binding Mag5}" Height="{Binding Mag5}" Fill="{Binding MagColor}"/>
<!--<TextBlock Text="{Binding Mag}"/>-->
</Grid>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:MapControl>
</Grid>
And add panel code.
StackPanel sp = new StackPanel();
sp.Background = new SolidColorBrush(Colors.White);
sp.CornerRadius = new CornerRadius(15);
sp.BorderBrush = new SolidColorBrush(Colors.LightGray);
sp.BorderThickness = new Thickness(1);
sp.Width = 260;
sp.MinHeight = 180;
sp.Padding = new Thickness(10);
Canvas.SetZIndex(sp, 99999);
mapControl.Children.Add(sp);
Windows.UI.Xaml.Controls.Maps.MapControl.SetLocation(sp, new Geopoint(new BasicGeoposition { Longitude = (double)fi.geometry.coordinates[0], Latitude = (double)fi.geometry.coordinates[1] }));
Windows.UI.Xaml.Controls.Maps.MapControl.SetNormalizedAnchorPoint(sp, new Point(0.5, 1));
Your way of setting the ZIndex wouldn't work because the StackPanel and the items inside MapItemsControl are in different hosts.
With the help of Live Visual Tree, you can find out how exactly they get laid out.
In the screenshot above, the StackPanel's host (i.e. the first Canvas) is placed behind the MapOverlayPresenters host (i.e. the second Canvas where MapItemsControl is inserted). So in order to have the StackPanel sit above them, you will need to manually set the ZIndex of the first Canvas to 1.
Once you understand this, the solution becomes simple -
Loaded += (s, e) =>
{
// GetChildByName comes from
// https://github.com/JustinXinLiu/Continuity/blob/0cc3d7556c747a060d40bae089b80eb845da84fa/Continuity/Extensions/UtilExtensions.cs#L44
var layerGrid = mapControl.GetChildByName<Grid>("LayerGrid");
var canvas1 = layerGrid.Children.First();
Canvas.SetZIndex(canvas1, 1);
};
Hope this helps!

Change Button XAML to C#

I have a tab control in which I am adding tab items programmatically. I want to have a close button with each tab item. On googling I found below XAML code for it:
<Button Content="X" Cursor="Hand" DockPanel.Dock="Right"
Focusable="False" FontFamily="Courier" FontSize="9"
FontWeight="Bold" Margin="5,0,0,0" Width="16" Height="16" />
Now, I am converting this code into equivalent C# code and struggling with some of the properties. Below given is the code which I have till now.
var CloseButton = new Button()
{
Content = "X",
Focusable = false,
FontFamily = FontFamily = new System.Windows.Media.FontFamily("Courier"),
FontSize = 9,
Margin = new Thickness(5, 0, 0, 0),
Width = 16,
Height = 16
};
I want help with properties like Cursor, DockPanel.Dock. Any help on this is much appreciated. Thanks !
Cursors are a fairly standard set of types. There are static classes out there that give you access to many of them. Use the Cursors class to get the Hand.
DockPanel.Dock is an attached property, it's not a property of the button control. You have to use the property setters for that dependency object or other convenience methods if available.
var button = new Button
{
Content = "X",
Cursor = Cursors.Hand,
Focusable = false,
FontFamily = new FontFamily("Courier"),
FontSize = 9,
Margin = new Thickness(5, 0, 0, 0),
Width = 16,
Height = 16
};
// this is how the framework typically sets values on objects
button.SetValue(DockPanel.DockProperty, Dock.Right);
// or using the convenience method provided by the owning `DockPanel`
DockPanel.SetDock(button, Dock.Right);
Then to set the bindings, create the appropriate binding object and pass it to the element's SetBinding method:
button.SetBinding(Button.CommandProperty, new Binding("DataContext.CloseCommand")
{
RelativeSource = new RelativeSource { AncestorType = typeof(TabControl) },
});
button.SetBinding(Button.CommandParameterProperty, new Binding("Header"));

How to put an image in a progress bar programmatically (WPF)

I'm completely new to WPF and I need some help putting an image in my progress bar (programmatically).
I found this (and it works):
<ProgressBar.Template>
<ControlTemplate>
<Grid>
<Image Name="PART_Track" Source="MyImage" Stretch="Fill"/>
<Rectangle Name="PART_Indicator" Fill="BlanchedAlmond" HorizontalAlignment="Left"/>
</Grid>
</ControlTemplate>
</ProgressBar.Template>
I just need some help converting that XAML code to C# code.
This will get you started :
FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));
FrameworkElementFactory image = new FrameworkElementFactory(typeof(Image));
image.Name = "PART_Track";
ImageSource source = new BitmapImage(...); // create it
image.SetValue(Image.SourceProperty, source);
image.SetValue(Image.StretchProperty, Stretch.Fill);
grid.AppendChild(image);
FrameworkElementFactory rectangle = new FrameworkElementFactory(typeof(Rectangle));
rectangle.Name = "PART_Indicator";
rectangle.SetValue(Rectangle.FillProperty, new SolidColorBrush(Colors.BlanchedAlmond));
rectangle.SetValue(Rectangle.HorizontalAlignmentProperty, HorizontalAlignment.Left);
grid.AppendChild(rectangle);
ControlTemplate ct = new ControlTemplate(typeof(ProgressBar));
ct.VisualTree = grid;
MyProgressBar1.Template = ct;

ExpanderView assigning DataTemplate

I've got a StackPanel which I need to fill in with ExpanderViews based on my data.
I am creating the ExpanderViews in code-behind and assigning to it, the DataTemplate present in the XAML.
The problem is, I am able to create the ExpanderView programmatically, but the DataTemplate approach doesn't work. All I can see is the "Expander Header" which doesn't show the items after click.
However, I can add Items manually to the ExpanderView and it shows the Items.
Please help!
C# Code:
ExpanderView expandOne = new ExpanderView()
{
Width = 400,
Margin = new Thickness(2),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Expander = new Border()
{
Width = 400,
Background = new SolidColorBrush(Colors.Brown),
Child = new TextBlock()
{
Text = "Expander Header",
FontSize = 34,
Foreground = new SolidColorBrush(Colors.Black),
Margin = new Thickness(40, 5, 5, 5),
},
},
};
// Assign DataTemplate
DataTemplate temp = (DataTemplate)FindName("ItemTemplateName");
expandOne.ItemTemplate = temp;
// add ExpanderView to StackPanel
this.MyStackPanel.Children.Add(expandOne);
XAML Code:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="ItemTemplateKey" x:Name="ItemTemplateName">
<ListBox Grid.Row="0" x:Name="ItemListBox">
<ListBox.Items>
<TextBlock Text="Filter Content 1" Foreground="Black"/>
<TextBlock Text="Filter Content 2" Foreground="Black"/>
<TextBlock Text="Filter Content 3" Foreground="Black"/>
</ListBox.Items>
</ListBox>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
If anyone still looking for an answer, I solved this by using the solution mentioned in
DataBinding to WP8 Toolkit ExpanderView

How to add a StackPanel in a Button in C# code behind

How to add a StackPanel in a Button using c# code behind (i.e. convert the following XAML to C# )? There is no Button.Children.Add...
<Button>
<StackPanel Orientation="Horizontal" Margin="10">
<Image Source="foo.png"/>
</StackPanel>
</Button>
Image img = new Image();
img.Source = new BitmapImage(new Uri("foo.png"));
StackPanel stackPnl = new StackPanel();
stackPnl.Orientation = Orientation.Horizontal;
stackPnl.Margin = new Thickness(10);
stackPnl.Children.Add(img);
Button btn = new Button();
btn.Content = stackPnl;
Set Button.Content instead of using Button.Children.Add
As a longer explanation:
Button is a control which "only has 1 child" - its Content.
Only very few controls (generally "Panels") can contain a list of zero or more Children - e.g. StackPanel, Grid, WrapPanel, Canvas, etc.
As your code already shows, you can set the Content of a Button to be a Panel - this would ehn allow you to then add multiple child controls. However, really in your example, then there is no need to have the StackPanel as well as the Image. It seems like your StackPanel is only adding Padding - and you could add the Padding to the Image rather than to the StackPanel if you wanted to.
Use like this
<Window.Resources>
<ImageSource x:Key="LeftMenuBackgroundImage">index.jpg</ImageSource>
<ImageBrush x:Key="LeftMenuBackgroundImageBrush"
ImageSource="{DynamicResource LeftMenuBackgroundImage}"/>
</Window.Resources>
and in Codebehind
Button btn = new Button();
btn.HorizontalContentAlignment = HorizontalAlignment.Stretch;
btn.VerticalContentAlignment = VerticalAlignment.Stretch;
StackPanel stk = new StackPanel();
stk.Orientation = Orientation.Horizontal;
stk.Margin = new Thickness(10, 10, 10, 10);
stk.SetResourceReference(StackPanel.BackgroundProperty, "LeftMenuBackgroundImageBrush");
btn.Content = stk;
In Xaml :
<Button x:Name="Btn" Click="Btn_Click" Orientation="Horizontal" Margin="10">
<StackPanel>
<Image Source="foo.png" Height="16" Width="16"/>
</StackPanel>
</Button>
In C# :
Button btn = new Button();
StackPanel panel = new StackPanel();
Image img = new Image
{
Source = "../foo.png"
}
panel.Children.Add(img);
btn.Content = panel;
I advise you to put the image in xaml resources :
<Window.Resources>
<BitmapImage x:Key="Img" UriSource="/Img/foo.png"/>
</Window.Resources>
And call it like this :
Image img = new Image
{
Source = (BitmapImage)FindResource("Img")
};

Categories