I'm trying to set font size dynamically in WPF. Here what i did so far.
App.xaml
<Style TargetType="{x:Type FrameworkElement}" x:key="baseStyle"></Style>
<Style TargetType="{x:Type TextBlock}" BasedOn={StaticResource baseStyle}"/>
App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
double fontSize = System.Drawing.SystemFonts.IconTitleFont.Size;
Style style = new Style{ TargetType = typeof(FrameworkElement)};
style.Setter.Add(new Setter(TextElement.FontSizeProperty, fontSize));
Application.Current.Resources["baseStyle"] = style;
}
}
MainWindow.xaml
<TextBlock Text="This is Sparta!!!"/>
Issue:
When the OnStartup called the resource 'baseStyle' is not available. So the style is assigned to Null value due to which the style is not applied. Anyone having idea to implement it in some other way. Your help will be appreciated.
Edit:
There is one thing that i would like to clarify. In reality i have wrote that App.xaml and App.xaml.cs code in resource dictionary and merged it in App.xaml. The code written in OnStartup is written in constructor of that code behind class.
With a little modification your code works. Just remove and add the base style
Style style = new Style { TargetType = typeof(FrameworkElement) };
style.Setters.Add(new Setter(TextElement.FontSizeProperty, fontSize));
Application.Current.Resources.Remove("baseStyle");
Application.Current.Resources.Add("baseStyle" , style);
Related
I need to apply style in grid resources programmatically in code behind.
I've the following snippet of code :
<Grid x:Name="grid">
<Grid.Resources>
<Style TargetType="{x:Type ig:LabelPresenter}">
<EventSetter Event="PreviewMouseMove" Handler="LabelPresenter_PreviewMouseMove"/>
</Style>
</Grid.Resources>
.
.
.
</Grid>
I want to create the Style in code behind and add this to resources for handle the relative action.
I tried to do this in this way but it dosen't work.
public MainWindow()
{
InitializeComponent();
var style = new Style { TargetType = typeof(LabelPresenter) };
var eventSetter = new EventSetter(PreviewMouseMoveEvent, new MouseButtonEventHandler(LabelPresenter_PreviewMouseMove));
style.Setters.Add(eventSetter);
grid.Resources.Add("style", style);
}
Where I'm wrong?
Thanks in advance.
EDIT: I wrote wrong grid's name. The grid's right name is grid
The style defined in the XAML markup is implicit, i.e. it has no x:Key. So change the first argument that you are passing to the Add method to typeof(LabelPresenter).
Also, a PreviewMouseMove event handler accepts a MouseEventArgs:
var style = new Style { TargetType = typeof(LabelPresenter) };
var eventSetter = new EventSetter(PreviewMouseMoveEvent, new MouseEventHandler(LabelPresenter_PreviewMouseMove));
style.Setters.Add(eventSetter);
grid.Resources.Add(typeof(LabelPresenter), style);
I have this custom control with my own logic
public class BackButton : Button
{
public BackButton()
{
this.DefaultStyleKey = typeof(Button);
this.Click += (s, e) => {
Services.NavigationService.GoBack();
};
}
}
I want to apply to it the default style BackButtonStyle. I do not want to edit StandardStyles.xaml so it's in another ResourceDictionary
<Style TargetType="controls:BackButton" BasedOn="{StaticResource BackButtonStyle}"/>
Referenced in App.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Common/StandardStyles.xaml"/>
<ResourceDictionary Source="Common/FrameworkStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
It is building but this exception is thrown :
Message = "Cannot find a Resource with the Name/Key BackButtonStyle [Line: 15 Position: 44]"
What am i doing wrong ?
BackButtonStyle has target type as Button, so you can't use BackButtonStyle as base style for target type of controls:BackButton.
<Style x:Key="BackButtonStyle" TargetType="Button">
I've got a simple custom control :
namespace Application.Custom_Controls
{
public class ReadOnlyTextBox : TextBox
{
public ReadOnlyTextBox()
{
this.DefaultStyleKey = typeof(ReadOnlyTextBox);
this.IsReadOnly = true;
}
}
}
And a custom style to make the control look like a TextBlock (in App.xaml).
<Application
x:Class="Application.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:tb = "clr-namespace:Application.Custom_Controls"
>
<!--Application Resources-->
<Application.Resources>
<Style x:Key="ReadOnlyTextBox" TargetType="tb:ReadOnlyTextBox">
//...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="tb:ReadOnlyTextBox">
//...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But when I'm using it in my application it does'nt display at all.
It diplays as a normal TextBox if I remove this.DefaultStyleKey = typeof(ReadOnlyTextBox);.
How to apply this style to my custom control in code behind ?
By the way, this style works well in xaml with Style="{StaticResource ReadOnlyTextBox}", but I can't use xaml in this case.
Thanks in advance.
this.Style = (Style)Application.Current.Resources["ReadOnlyTextBox"];
Add this line to the constructor of the ReadOnlyTextBox
I have made a very simple test project:
MainWindow.xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel x:Name="mainPanel" />
</Window>
MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyTextBox myTextBox = new MyTextBox("some text here");
mainPanel.Children.Add(myTextBox);
}
}
}
MyTextBox.cs:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Test
{
class MyTextBox : TextBox
{
static MyTextBox()
{
MyTextBox.BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(Brushes.Red));
}
public MyTextBox(string Content)
{
Text = Content;
}
}
}
this, in order to test the metaData Overriding function.
now the trouble is: this does not work as I expected it to...
indeed, the MyTextBox's background is white, and not Red.
I investigated and tried this as constructor for my custom class:
public MyTextBox(string Content)
{
Text = Content;
Background = Brushes.Blue;
ClearValue(BackgroundProperty);
}
now here is what I found out when I debugged:
in the main class:
MyTextBox myTextBox = new MyTextBox("some text here");
we go into the custom class's static constructor, then in the instance's constructor:
Text = Content; >> Background = Red
Background = Brushes.Blue; >> Background = Blue
ClearValue(BackgroundProperty); >> Background = Red again (as expected)
we go back to the main class:
mainPanel.Children.Add(myTextBox);
... and right after this line of code, myTextBox.Background is White.
Question: Why?
why is this set to white when I add it to the mainPanel??? I cannot find any logical explanation to this...
furthermore, if I add some more code where I do something like: myTextBox.Background = Brushes.Blue; and then myTextBox.ClearValue(MyTextBox.BackgroundProperty);, it becomes Blue then White again, instead of Red.
I don't understand.
The Background is being set by the default Style of the TextBox. Based on the Dependency Property Value Precedence Red is at #11, while the default Style is at #9. The Blue setting would be at #3, so that should override the Background fine.
You would either have to set the background explicitly (like you do with the Blue brush), or create your own custom default style that doesn't set the Background. Your default style can be based on the TextBox version.
You can set Background in a style applied to your MyTextBox:
<Application.Resources>
<Style TargetType="local:MyTextBox">
<Setter Property="Background" Value="Red" />
</Style>
</Application.Resources>
As CodeNaked mentioned your default metadata value is being overriden by default style for textbox. You can see it if you will change your code:
MyTextBox.cs:
Control.BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(Brushes.Red,
FrameworkPropertyMetadataOptions.Inherits, PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
// set breakpoint here
}
When breakpoint will be breaked you will be able to see that OldValue was Red, NewValue is White and from stack-trace you can see that it happens because of default style being applied.
I am trying to add control to ContentPresenter on then run, but control I've added does not apply theme.
Theres is code with reference to theme in xaml file:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/PocGraphDataTemplates.xaml" />
</ResourceDictionary.MergedDictionaries>
Also I've tried to set style in code behind, does not work:
this.graphLayout.Content = analyzerViewModel.AnalyzedLayout = new PocGraphLayout()
{
LayoutAlgorithmType = "FR"
};
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri("Resources/PocGraphDataTemplates.xaml", UriKind.Relative);
analyzerViewModel.AnalyzedLayout.Style = new Style(typeof(PocGraphLayout));
analyzerViewModel.AnalyzedLayout.Style.Resources.MergedDictionaries.Add(rd);
When control was static everything worked fine:
<ViewModel:PocGraphLayout x:Name="graphLayout"
Graph="{Binding Path=Graph}"
LayoutAlgorithmType="{Binding Path=LayoutAlgorithmType}"
Sample:LayoutManager.ManagedLayout="True"
OverlapRemovalAlgorithmType="FSA"
HighlightAlgorithmType="Simple" />
Any ideas?
PS. I am newbie in wpf.
just see the style applied are using DynamicResource instead of StaticResource