In my XAML I have this:
<Color x:Key="VeryLightGrey">#fff0f0f0</Color>
<Color x:Key="TabBackgroundColor">#fff0f0f0</Color>
I would love to have something like this:
<Color x:Key="TabBackgroundColor" Color="{StaticResource VeryLightGrey}"/>
I have tried various methods including this:
<StaticResource x:Key="TabBackgroundColor" ResourceKey="VeryLightGrey"/>
But my code become riddled with warning about:
"An object of type System.Wndows.StaticResourceExtention cannot be applied to a property that expects the type System.Windows.Media.Color"
Other posts say to ignore this warning, but it actually causes problems, so i cant.
Is there a better solution out there ?
You could declare the color once and define multiple brushes that use the same color.
Use the Brushes for your UI Elements.
Related
Is it possible in XAML to add a reference to resource? For example I have
<Color x:Key="LightRed">#e24c3f</Color>
and I need to have something like
<Color x:Key="ErrorColor">*LightRed*</Color>.
No, a Color resource cannot reference another Color resource if that's what you are asking.
As suggested by #Nawed Nabi Zada, you may define a brush that uses any color resource though:
<SolidColorBrush x:Key="ErrorBrush" Color="{StaticResource LightRed}"/>
You can easily change the colour of the brush in one place.
I want to define some resources in my App.Xaml for fontsize.
This type of thing will work:
<sys:Double x:Key="FontLarge">24</sys:Double>
But I want to get the value from a :xStatic so something like this:
<sys:Double x:Key="FontLarge">{x:Static local:Settings.FontLarge</sys:Double>
or
<sys:Double x:Key="FontLarge" Value="{x:Static local:Settings.FontLarge"></sys:Double>
Neither of these work though. Is this possible and what would be the syntax?
I don't think that there is a way to bind Double value using x:Static (I may be wrong though).
But there is always a way using code behind which you can use. If this is meant to be in App.Xaml, you can write
App.Current.Resources.Add("FontLarge", Settings.FontLarge);
If some other class, you can just drop the App.Current and that would work.
I am creating a custom control with two text colors, ColorA and ColorB. ColorA is wired to the Foreground property of the control, and ColorB is wired to a custom dependency property called ForegroundAlt. Both properties are Brush objects. The control's XAML gets the property values using this markup:
<SolidColorBrush x:Key="BrushA" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
<SolidColorBrush x:Key="BrushB" Color="{Binding Path=ForegroundAlt, RelativeSource={RelativeSource TemplatedParent}}" />
I need to animate sme text between the two colors in the control template, and that's where I am running into problems.
Normally, I would simply create a data binding to each Brush.Color property, like this:
To="{Binding Source={StaticResource BrushB}, Path=Color}"
But that won't work here. It turns out that you can't use bindings on an animation inside a control template.
As a workaround, I would like to create a pair of Color resources to go along with the Brush resources:
<Color x:Key="ColorA" ??? />
<Color x:Key="ColorB" ??? />
Each Color resource should have the color of its corresponding brush. I could then reference the colors as static resources, and avoid having to data bind from within the animation.
So, here are my questions:
-- How would I declare the Color resources?
-- Is there a simpler way to get the job done?
Thanks for your help.
If I've understood this correctly, what you are trying will not work. Even if you define the Colors as resources, you will still have to bind them to the brush resources and you are back to square one!
One solution is to do it in code behind rather than in the template. Since its a custom control you are building its should be pretty straightforward to add it in th code behind without screwing up the design.
I implemented skinning in my application. The application loads its Brushes.xaml resource dictionary which uses colors which reside in a skin-specific resource dictionary. So only one Color.xaml is loaded depending on the chosen skin.
Skin-Specific Color.xaml
<Color x:Key="TextBoxBackgroundColor">#C4AF8D</Color>
<Color x:Key="TextBoxForegroundColor">#6B4E2C</Color>
<Color x:Key="ToolBarButtonForegroundColor">#6B4E2C</Color>
Brushes.xaml:
<SolidColorBrush
x:Key="TextBoxBackground"
Color="{DynamicResource TextBoxBackgroundColor}" />
<SolidColorBrush
x:Key="TextBoxForeground"
Color="{DynamicResource TextBoxForegroundColor}" />
As you can see, multiple colors (TextBoxForegroundColor and ToolBarButtonForegroundColor) are the same. I'd like to circumvent that as it is getting more and more confusing especially since the used colors are not recognizable by their hex value. You could advise now to merge both Colors into one but I have skins where the TextBoxForegroundColor is different from the ToolBarButtonForegroundColor.
What I would like to do is something like this:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} />
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} />
Is this at all possible in Xaml? I didn't find a way.
This?
<Color x:Key="DarkBrown">#C4AF8D</Color>
<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/>
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/>
For more advanced use cases and multiple levels of aliasing see this answer.
Why don't you just make Brushes.xaml skin-specific? Then you will have this:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color="{StaticResource DarkBrown}" />
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color="{StaticResource DarkBrown}" />
Another point in favor of making brushes skin-specific is that there are situations where you would want to make the ToolBarButtonForegroundBrush a solid color brush in one skin and a gradient brush in another skin.
H.B.'s answer is very interesting and I have played around with it quite a bit since I want to do exactly what this question is asking to do.
What I've noticed is that using a DynamicResource doesn't work for WPF 3.5. That is, it throws an exception at run time (the one Amenti talks about). However, if you make colors that are referencing the color you want to share ... a StaticResource, it works on both WPF 3.5 and WPF 4.0.
That is, this xaml works for both WPF 3.5 and WPF 4.0:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ColorsReferencingColors.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480"
>
<Window.Resources>
<Color x:Key="DarkBlue">DarkBlue</Color>
<StaticResource x:Key="EllipseBackgroundColor" ResourceKey="DarkBlue"/>
<SolidColorBrush
x:Key="ellipseFillBrush"
Color="{DynamicResource EllipseBackgroundColor}"
/>
</Window.Resources>
<Grid>
<StackPanel Margin="25">
<Ellipse
Width="200"
Height="200"
Fill="{DynamicResource ellipseFillBrush}"
/>
</StackPanel>
</Grid>
</Window>
Another thing that bears mentioning (again) is that this approach wreaks havoc with the designers out there (i.e the Visual Studio 2008 and 2010 designers, the Blend 3 and 4 designers). I speculate that this is the same reason why Kaxaml 1.7 wasn't liking H.B.'s xaml (if you're following the comment stream on H.B.'s answer).
But while it breaks the designers for a simple test case, it doesn't seem to break the design surface for the large scale application I work on in my day job. Plain weird! In other words, if you care about things still working in the designer, try this method out anyway ... your designer may still work!
That last part is not possible as a Color has no Color property.
A Color does have an R, G, B and A property. So you could create four bytes as resources:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Byte x:Key="r">#23</sys:Byte>
<sys:Byte x:Key="g">#45</sys:Byte>
<sys:Byte x:Key="b">#67</sys:Byte>
<sys:Byte x:Key="a">#FF</sys:Byte>
<Color x:Key="c1" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
<Color x:Key="c2" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
</ResourceDictionary>
Still not what you might prefer but it should work.
I've create a style for ListItems that I want to use across all ListBoxes in my application. I can set these manually like so:
<ListBox ItemContainerStyle="">
But I'm having trouble getting the style to apply to every single ListBox in my application without touching each one and adding the above attribute.
In addition, and more importantly, I want to apply the style to list boxes used within custom templated controls. Right now I have to modify the Generic.xaml theme in the control library... not something i think I should have to do.
Fairly certain this has something to do with themes, btu having a heck of a time figuring it out.
You can do this with implicit styles in Silverlight 4.
Define your style in the regular way:
<Style x:Key="DefaultListBoxStyle" TargetType="ListBox">
....
<Style>
then create the implicit style:
<Style TargetType="ListBox"
BasedOn="{StaticResource DefaultListBoxStyle}" />
you could use implicit styles.
http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx
You define one global style for a type (in your case ListBoxItem) and then this style is the new default style for your app.
If you need any further information, just leave a comment.
BR,
TJ