How to make smaller points on a Silverlight Toolkit's LineChart? - silverlight

By default if you take a look at the Silverlight toolkit demo site,
http://silverlight.net/content/samples/sl3/toolkitcontrolsamples/run/default.html
you will see on the LineChart some points which are relatively big.
As far as I know every point on the Chart is an Ellipse.
For that I created the style on xaml file.
<Style x:Name="ChartLineBar" TargetType="Ellipse">
<Setter Property="Width" Value="10"/>
<Setter Property="Height" Value="10"/>
</Style>
and bind like this:
series.DataPointStyle = Resources["ChartLineBar"] as Style;
This did not work, so after that I decided to like that:
I basically recreate the structure which are showing the points.
<Style x:Name="ChartLineBar" TargetType="chartingToolkit:LineDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:LineDataPoint">
<Grid x:Name="Root">
<Ellipse Width="10" Height="10" Visibility="Visible" Opacity="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This did not work either, but I think that there should exist a solution for that because, if I use the SilverlightSpy, I can access all the properties and if I modify there the point's size is decreasing.
How can I make smaller points on a silverlight LineChart?

The July 09 source code shows the default width and height to be 8 so I'm not sure setting them to 10 would make them smaller.
Have you tried it like this:-
<Style x:Name="ChartLineBar" TargetType="chartingToolkit:LineDataPoint">
<Setter Property="Width" Value="10"/>
<Setter Property="Height" Value="10"/>
</Style>
Note that the TargetType is LineDataPoint.

Related

How to make an exception for Application.Resources style in a specific Grid.Resources

I am doing small WPF app for my own using Visual Studio, C#, .NET Standard and WPF in this specific project.
I have defined style for all TextBlocks and TextBoxes in Applications.Resources like below.
<Application.Resources>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="10"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
</Style>
</Application.Resources>
Then in main window I have a grid which contains some buttons.
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="FontSize" Value="50" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="50"/>
</Style>
</Grid.Resources>
<Button Grid.Column="0" Content="DASHBOARD" Command="local:CustomCommands.ShowDashboard"/>
</Grid>
I would like to set for the textblocks/textboxes in this specific buttons a wider font.
I tried for many different syntax but could not manage it. I tried also do define x:Key for this style in Grid.Resources and use it in this specific Button control. This wasn't work either.
Can anyone let me know which way should I let know my application that text in this buttons would have bigger font size?
The TextBlock created for string contents by the ContentPresenter inside the Button template doesn't apply the locally-defined resources, i.e. those in your Grid.
The easiest way to solve your problem would be to explicitly define a TextBlock as the Button's content.
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="50"/>
</Style>
</Grid.Resources>
<Button Grid.Column="0" Command="local:CustomCommands.ShowDashboard">
<TextBlock Text="DASHBOARD" />
</Button>
</Grid>

How to set specific control element settings that override a global style in WPF?

I have defined a global style for Buttons in my application via an application-wide Resource Dictionary. The style looks like this (followed from another SO Example):
<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="{DynamicResource BaseButtonBG}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!-- Triggers here -->>
</Style.Triggers>
It works. But I need to assign specific values directly to some of my buttons, like margin and padding to align them. I also would like to have the ability to override the color properties from the style in individual buttons.
It appears that any properties I set directly on specific buttons get completely ignored and only the properties from the global style are used. How do I overcome this?
UPDATE: To clarify what I want:
In the HTML/CSS world (which is older than dirt), you can add a style class to an element, but you can also assign properties directly to the element that override the class values. That's what I want to accomplish in WPF.
UPDATE 2
It's possible people think this question is stupid because the solution should be obvious. However, from my personal testing, there appears to be a bug with Padding not changing at all unless you specifically bind it in a control template. This behavior seems to change from property to property. Since my original attempt to override a property specifically involved Padding and it didn't work, I had to build this workaround.
Ok, form in Design:
XAML code for form:
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Content="Button" x:Name="btnNo1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120"/>
<Button Content="Button" x:Name="btnNo2" HorizontalAlignment="Left" Margin="135,10,0,0" VerticalAlignment="Top" Width="120"/>
</Grid>
and in RunTime we going to change Margin by using this code in CS file:
public MainWindow()
{
InitializeComponent();
btnNo2.Margin = new Thickness(100, 100, 100, 100);
}
Result will be:
Can you create and use new style for button where you need custom margin/padding?
<Style x:Key="SpecialButtonType1" BasedOn="{StaticResource ResourceKey=CommonButtonStyle}">
...
</Style>
and change
<Style TargetType="Button">
to
<Style TargetType="Button" x:Key="CommonButtonStyle">
YES: It's completely doable, You can assign overriding properties directly on an element without doing the ugly process many are using of creating a special one-off dictionary entry just for the specific element in question.
I don't know if its caused by a bug in WPF, but there's an initial requirement...
Your dictionary-referenced base style might need to include any properties that you want to be overridable. For some reason different properties seem to exhibit different behavior. But at least in the case of Padding, if you don't include Padding on your ControlTemplate TemplateBinding, you won't be able to override it on your element.
Additionally, in the case of margin, there seems to be some kind of "doubling" effect that happens if you include Margin in the ControlTemplate TemplateBinding. If you don't templateblind the margin, you can still override margin but the behavior changes.
STEP 1
Define a base style with a ControlTemplate. Make sure that your ControlTemplate includes a TemplateBinding for all properties that you may want to customize/override on individual elements.
<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="{StaticResource BaseButtonBG}"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
Margin="{TemplateBinding Margin}"
>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BaseButtonBG_IsMouseOver}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource BaseButtonBG_IsPressed}"/>
</Trigger>
</Style.Triggers>
</Style>
I've defined a few StaticResource keys for my property colors so that I can put them altogether in another place for cleaner skinning. Here are those keys:
<SolidColorBrush x:Key="BaseButtonBG" Color="#5f636c"/>
<SolidColorBrush x:Key="BaseButtonBG_IsMouseOver" Color="#898C94"/>
<SolidColorBrush x:Key="BaseButtonBG_IsPressed" Color="#484B51"/>
STEP 2
Implement actual button like this:
<Button Content="New" />
And the result of this makes a button that looks like this:
STEP 3
Now let's say I want all of my buttons to look squashed like that, except one. I want to add some vertical padding to make one specific button look taller. I could alter the example button like this:
<Button Content="New" Padding="0,30"/>
And the result:
Alternatively, you could implement the button override as follows, which gives you the ability to override Triggers or other special Style options.
<Button Content="New">
<Button.Style >
<Style TargetType="Button" BasedOn="{DynamicResource {x:Type Button}}">
<Setter Property="Padding" Value="0,30"/>
</Style>
</Button.Style>
</Button>
TADA! We've assigned a one-off style tweak directly to the element WHERE IT BELONGS! We didn't have to create a style in a dictionary and reference it for this one case.
Important Points
In order to make this work "Padding" MUST BE defined in the ControlTemplate with the TemplateBinding code. If you don't do that, Padding directly applied to the button just gets ignored completely. Again, I'm not sure why its like this, but that seems to be the magic fix.
Further Reading: I was able to figure this out from some helpful info on this blog article:
explicit-implicit-and-default-styles-in-wpf
Interestingly, the last part of that article suggests creating a custom control with your own default style and properties that you can override similarly to how I've done here. This seems a bit overkill to me, but it might eliminate the weird bugginess problem with padding and margin behaving differently. Haven't tried that yet, though.

Use trigger to change colour of a path declared in ResourceDictionary

I'm creating a radiobutton style. The RadioButton has a Border which hosts a ContentControl. The ContentControl has its Content property set to a Path (FemaleVector) declared in a separate ResourceDictionary. How can I change the Fill property of the path when the radiobutton IsChecked? Below is what I have so far. I am able to change the background property of the border but setting the Foreground property of the ContentControl does not change the colour of the path. (Didn't think that would work.)
<Style x:Key="Female" TargetType="{x:Type RadioButton}">
<Setter Property="Margin" Value="0,0,5,0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border x:Name="border" Padding="7,3,7,3" Width="35" Height="35" BorderBrush="#8CD567DC" Background="#00D567DC" CornerRadius="5" BorderThickness="0.8">
<ContentControl x:Name="content" Content="{DynamicResource FemaleVector}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="border" Value="#8CD567DC"/>
<Setter Property="Foreground" TargetName="content" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I don't like having the long Data property of paths in my Styles, so I have moved them into a separate ResourceDictionary. Should I just put the Path back into my Style instead of keeping it in a separate ResourceDictionary?
Edit: similar questions are here and here.
If the style is not reused somewhere, I would personally keep it in local style resources section. That way you see bigger picture. Otherwise it would be wise to keep it in ResourceDictionary :)
Either way you should be able to change Fill property with:
<Setter Property="Content.Fill" TargetName="content" Value="Blue"/>
If this is not working, I advise few ways more:
You can use Trigger.EnterActions<> in Xaml. Perhaps setting property through animation will have better effect? ControlTemplate triggers with setters are sometimes way limiting.
There's also relative binding. But you gotta be careful with that. (If you pla to make it reusable)
In your FemaleVector style, you can bind Fill against ContentControl Foreground. Look for RelativeBinding in Google.
And then there's property inheritance. If you set Fill color in FemaleVector, you need to do it with style. Such as:
<Style>
<Setter Property="Fill" Value="BLACK" />
</Style>
you can later set ContentControls Style and add trigger there, like:
<ContentControl.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding={Binding IsChecked, RelativeSource={RelativeSource AncestorType=RadioButto}} Value=TRUE>
<Setter Property="Path.Fill" Value="BLACK" />
</DataTrigger>

Can You Make A Small Adjustment To A Style Based On Another Style In XAML

Is it possible to make small adjustments to styles based on other styles in XAML, I want to do something like this:
<Style TargetType="{x:PseudoType MostControls}" x:Key="WhatMostControlsLookLike">
<Setter Property="Margin" Value="10" />
</Style>
<Style TargetType="{x:PseudoType ThisControl}"
x:Key="WhatThisControlLooksLike"
BasedOn={StaticResource WhatMostControlsLookLike}">
<Setter Property="Margin">
<Setter.Value>
<!-- Top, Right, and Bottom are 10 as per WhatMostControlsLookLike-->
<Thickness>
<!-- But Left is 10 times as thick-->
<Thickness.Left>100</Thickness.Left>
</Thickness>
</Setter.Value>
</Setter>
</Style>
No, that's not possible. You have to completely replace the Margin when setting it again.

Why must I use "Resources" in WPF?

I'm just diving into WPF and find this a little odd and frustrating to my style: Why can the value of something be a Resource but you can't set the value directly to what the Resource represents? Example:
This is valid:
<ToggleButton>
<ToggleButton.Resources>
<Image x:Key="cancelImage" Source="cancel.png" />
</ToggleButton.Resources>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="{DynamicResource cancelImage}" />
</Style>
</ToggleButton.Style>
</ToggleButton>
But this is not:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Image Source="cancel.png" />
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
What is the difference? Why don't both work? I don't like having to create a "Resource" for some things because it divides my code up and can make it more difficult to read.
And yes, I do know my example can be simplified like this
<ToggleButton>
<Image Source="cancel.png" />
</ToggleButton>
but that's not the point.
When working with setters, the value for the setter has to support the ability to be "frozen". That can be a value type (including structs and enums), or a class that derives from Freezable.
It may not help your aesthetic sense much, but it is often cleaner to declare all your resources at the top of the Resources section of the file (or ResourceDictionary), as opposed to adding them to the Resources of an individual style or control.

Resources