App.xaml style cannot be used in Usercontrol, how come? - wpf

I have a style for a textblock that is set inside my app.xaml this is then applied to textblocked through out my application and works fine.
However i get an error: "could not create instance of type" if i apply this style to a textblock within my user control, how come this is a problem?
<UserControl x:Class="Client.Usercontrols.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinHeight="30" MinWidth="40"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Button Width="Auto" HorizontalAlignment="Center">
<Border CornerRadius="5" BorderThickness="1" BorderBrush="Transparent" >
<Grid>
<Image Name="tehImage" Source="{Binding ImageSource}" />
<TextBlock Name="tehText" Text="{Binding Text}"
Style="{StaticResource ButtonText}" /> <-- This causes error
</Grid>
</Border>
</Button>
Thanks,
Kohan
-- App.Xaml Code --
<Application x:Class="Client.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Mainpage.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/CascadingStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
-- CascadingStyles.Xaml --
<Style TargetType="{x:Type TextBlock}" x:Key="ButtonText" >
<Setter Property="FontSize" Value="10" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Lucida Sans Unicode" />
<Setter Property="Foreground" Value="#0F004E" />
</Style>

Basically, it can not find the StaticResource because it is not in the file with your user control. UserControl.xaml knows nothing about App.xaml.
You should use DynamicResource instead, this way it will be applied at runtime.

The previous answer is absolutely incorrect. You can definitely define resources at the application level and reference them from within UserControls. In fact, that can often increase performance to prevent resource duplication. Application resources are checked 3rd in the list for Static Resources as described on this page under the heading "Static resource lookup behavior".
I'm guessing you have a typo or some other problem causing your error. Could you post the app.xaml code?

I have lost some hours on such a problem, but it only applies to Expression Blend 4.
As explained in this blog post:
http://blogs.msdn.com/b/unnir/archive/2009/03/31/blend-wpf-and-resource-references.aspx
Expression will try to resolve StaticResources using the Blend Application.Resources instead of your application Application.Resources. This seems to happen still on Blend 4.0.30422.0

Related

Apply a style to all textbox in my WPF application

I am having an issue while I want to apply a style (font size) to all my textbox, where ever they are.
I, of course found those links :
Apply an application-level style to all textboxes
How to target all controls (WPF Styles)
But this doesn't work for me.
The first one is still better because you don't need to use a key, and going to all your textbox.
I already have, in my app.xml, style applying to all controls (applying a color), so I tried something like this (even if this won't really be enough for me, since those styles are not everywhere) :
<Style x:Key="Type1Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="#FEE9E6"/>
<Style.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="50" />
</Style>
</Style.Resources>
</Style>
And as I said, I tried this too, but won't work.
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="50" />
</Style>
Any idea what is my probleme and how I can achieve what I want to?
All the hings I can find make me come back to the same code, and didn't found one that works.
edit : here is my current app.xaml
<Application x:Class="myApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:myApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="TextBox"><!-- tried adding those 3 lines too-->
<Setter Property="FontSize" Value="50"/>
</Style>
<Style x:Key="Type1Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style x:Key="Type2Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="White"/>
</Style>
<Style x:Key="Type3Data" TargetType="{x:Type Control}">
<Setter Property="Background" Value="Green"/>
</Style>
</Application.Resources>
</Application>
As I said, the current styles does not cover the whole app (I add the key that is needed, or nothing)
edit : and if I add directly (as a second setter) font size to the Type 1,2 or 3, the font size apply. So it seems, there is no oter styles that are applying besides the 3 in app.xml.
<Setter Property="FontSize" Value="50" />
Sample of code who should get a different textbox size(one with already a style, one without), they are in grid:
<com:ViewControl x:Class="myApp.View.ViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:input="http://schemas.syncfusion.com/wpf"
xmlns:local="clr-namespace:myApp.View"
xmlns:com="clr-namespace:RAPINF.PLL.Common;assembly=myApp.Common"
xmlns:entities="clr-namespace:myApp.Entities;assembly=myApp.Entities"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="700">
<TextBox Style="{StaticResource Type1Data}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="2" Text="{Binding Data.Name}" VerticalAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1" Margin="2" Text="{Binding Data.Name}" VerticalAlignment="Center" Grid.ColumnSpan="3" />
edit : adding the code of the popup I use sometimes and works
<sf:RibbonWindow x:Class="namespace:myApp.Common.DetailViewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:sf="http://schemas.syncfusion.com/wpf"
xmlns:self="clr-namespace:myApp.Common"
mc:Ignorable="d"
d:Height="300" d:Width="400"
WindowStartupLocation="CenterOwner"
>
</sf:RibbonWindow>
How my usercontrol is added to the dock :
public void AddView(UserControl View, string sTitle, DockState docState)
{
int Width = 800;
int Height = 400;
DockingManager.SetHeader(View, sTitle);
DocumentContainer.SetMDIBounds(View, new Rect(30, 30, Width, Height));
DockingManager.SetState(View, docState);
DockingManager.SetShowCloseMenuItem(View, true);
DockingManager.SetDesiredWidthInDockedMode(View, Width);
DockManager.Children.Add(View);
ActivateView(View);
}
If I use the dock I do this before :
ApplicationContext.Current.AddView(View, DockState.Document);
ANd with a popup, almost the same :
DetailViewWindow dlg = new DetailViewWindow(View);
dlg.ShowDialog();
As, those two code are used with the same View (yes, exactly the same), then I guess the problem comes from the fact of adding the view in the dock, and not in a popup window.
Does the dock manager forces me to use a key?
Thank you for your help.
I can't reproduce your problem. I can just show you a working example. Maybe it's helping you finding your problem.
App.xaml
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize"
Value="50" />
</Style>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
Title="MainWindow"
Name="MyWindow"
SizeToContent="WidthAndHeight">
<TextBox Width="150"/>
</Window>
Output
I too had no problem with the styling. But I typically break my stuff into separate dictionaries for different controls and derive from some of my own classes. I also define a style and assign a "x:Key" name to it. This is like saying I have a class with this key name and I want it to look like this. Then, once I get it working, I take the final class and say use your style based on the key defined... Having said that, Here is a stripped basic of the App.xaml
<Application.Resources>
<Style TargetType="TextBox" x:Key="STextBox">
<Setter Property="FontSize" Value="50"/>
<Setter Property="FontFamily" Value="WingDings" />
</Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource STextBox}" />
</Application.Resources>
I can define all sorts of things about my base-style "STextBox" (via the x:Key). But after, I set the style with a target BASED ON the style via x:Key. The critical thing I think you were missing is the target must be of {x:Type TextBox}.
If you look at the xmlns headers at the top such as
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
the "x=" is the alias of the library it is getting control types. By you generically declaring the
TargetType="TextBox"
You are not specifically associating to the CLASS TYPE.
Then in my main window (and anywhere else in the app), I have this in my main grid
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="80" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="Testing" />
<TextBox Grid.Row="1" Text="Another Line" />
<TextBox Grid.Row="2" Text="Last" />
</Grid>
and they all work properly. You can also change default colors, size, font family, margins, etc to the base style and all will change without explicit reference to every control.

How to set a default Margin for all the controls on all my WPF windows?

I want to set a default Margin of 3 on all the controls I put on all my windows and be able to override this value just on a really few number of items.
I've seen some approaches like doing styles but then I need to style everything, I would prefer something than can be done for all the controls together. I've seen other things like the MarginSetter but looks like it does not traverse subpanels. I want the Margin only on the controls I put at the window, nothing to do with the borders or other things of the visual tree.
Looks something pretty basic to me. Any ideas?
Thanks in advance.
The only solution I can find is to apply the style to each of the controls you are using on the window (I know that's not quite what you want). If you're only using a few different control types it's not too onerous to do something like this:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- One style for each *type* of control on the window -->
<Style TargetType="TextBox">
<Setter Property="Margin" Value="10"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<StackPanel>
<TextBox Text="TextBox"/>
<TextBlock Text="TextBlock"/>
</StackPanel>
</Window>
Good luck...
You can link all of your Margin properties by referring to a "Thickness" defined in your resources. I just did this in a project...
<!-- somwhere in a resource-->
<Thickness x:Key="CommonMargin" Left="0" Right="14" Top="6" Bottom="0" />
<!-- Inside of a Style -->
<Style TargetType="{x:Type Control}" x:Key="MyStyle">
<Setter Property="Margin" Value="{StaticResource CommonMargin}" />
</Style>
<!-- Then call the style in a control -->
<Button Style="{StaticResource MyStyle}" />
<!-- Or directly on a Control -->
<Button Margin="{StaticResource CommonMargin}" />
The key for me was figuring out that Margin was defined by "Thickness". Let me know if that's clear enough or if you need me to put it in a fully working XAML example.
You can apply margin in your buttons style. And when you use buttons with this style in StackPanel wpf will apply need spacing.
for example
define in resourcedictionary or whatever:
<Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10"/>
....
</Style>
then in yor StackPanel xaml definition:
<StackPanel>
<Border BorderThickness="0"/>
<Button x:Name="VertBut1" Style="{StaticResource myButtonStyle}" Content="Button1"/>
<Button x:Name="VertBut2" Style="{StaticResource myButtonStyle}" Content="Button2"/>
<Button x:Name="VertBut3" Style="{StaticResource myButtonStyle}" Content="Button3"/>
</StackPanel>
regards
Georgi

How to write styles to callouts wpf

I'm using the next namespace (http://schemas.microsoft.com/expression/2010/drawing).
I've two controls for the collout which use the same styles.
i want to write some reusable style for those two controls, but no success...
Any suggestions?
You can reuse styles, whether it's for callouts or any other control, by making them resources and referencing them later. For example:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
x:Class="WpfApplication1.MainWindow">
<Window.Resources>
<Style x:Key="MyCalloutStyle" TargetType="ed:Callout">
<Setter Property="Fill" Value="Orange" />
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ed:Callout Style="{StaticResource MyCalloutStyle}" />
<ed:Callout Style="{StaticResource MyCalloutStyle}" />
</Grid>
</Window>

Setting VerticalAlignment property to all controls

My WPF UserControl contains two stack panels and each of them contains labels, text boxes and radio buttons.
I would like to set VerticalAlignment property to Center to all controls in my UserControl with as little code as possible.
Now I have following solutions:
brute force - put VerticalAlignment="Center" in each control
define one style for FrameworkElement and apply it directly
define styles for each type of the controls on user control (this needs 3 style definitions, but automatically applies style to the control)
These three solutions need too much code.
Is there any other way to write this?
I hoped that defining style for FrameworkElement would automatically set property to all controls, but it does not work.
Here is snippet of my current XAML (I omitted second, very similar stack panel):
<UserControl.Resources>
<Style x:Key="BaseStyle" TargetType="FrameworkElement">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource BaseStyle}" Text="Value:" />
<RadioButton Style="{StaticResource BaseStyle}">Standard</RadioButton>
<RadioButton Style="{StaticResource BaseStyle}">Other</RadioButton>
<TextBox Style="{StaticResource BaseStyle}" Width="40"/>
</StackPanel>
</Grid>
Edit:
Re Will's comment: I really hate idea of writing control formatting code in codebehind. XAML should be sufficient for this really simple user control.
Re Muad'Dib's comment: Controls I use in my user control are derived from FrameworkElement, so this is not an issue here.
I had come across the same conundrum awhile ago as well. Not sure if this is the "best" way, but it was easy enough to manage by defining your base style and then creating separate styles for each control on the page that inherited from the base style:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="300" Background="OrangeRed">
<Page.Resources>
<Style TargetType="FrameworkElement" x:Key="BaseStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,5,0" />
</Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="RadioButton" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="TextBox" BasedOn="{StaticResource BaseStyle}" />
</Page.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Value:" />
<RadioButton>Standard</RadioButton>
<RadioButton>Other</RadioButton>
<TextBox Width="75"/>
</StackPanel>
</Grid>
</Page>

Silverlight 4: XamlParseException when trying to bind with styles and resources

I am using Silverlight 4 and I am trying to integrate one of the themes from the Silverlight 4 toolkit from April.
My App.xaml reads as follows:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/System.Windows.Controls.Theming.ExpressionDark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
When my main window reads
<Grid x:Name="LayoutRoot" Background="{Binding Source={StaticResource ThemeBackgroundBrush}}">
<TextBlock Text="Test" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{Binding Source={StaticResource ThemeForegroundBrush}}" />
</Grid>
It works perfectly. However I would like to use resources so I went ahead and did the following
<Grid x:Name="LayoutRoot" Background="{Binding Source={StaticResource ThemeBackgroundBrush}}">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding Source={StaticResource ThemeForegroundBrush}}" />
</Style>
</Grid.Resources>
<TextBlock Text="Test" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
It fails :-(
I have tried to place the resource style in other places like the App.xaml etc.
Anyone know how I can use resources so I don't have to specify the foreground for each TextBlock?
PS - I am using the ExpressionDark theme...
Thanks in Advance,
Mike
I don't believe that you need the Binding Source part.
I have used the following
<Setter Property="Foreground" Value="{StaticResource ThemeForegroundBrush}" />
in the past and it works well.

Resources