How do you format in code AxisLabel for DependentRangeAxis? - wpf

I cannot get the axis to format as currency, any idea?
What am I doing wrong? I need to be able to change the formatting on the fly and for this test I wanted to set it as currency for the Y axis on the scale of values.
Anyone?
Thanks...
var columnSeries = new ColumnSeries
{ Title = reportProcedureNode.Value,
IndependentValuePath = "PrimaryKey",
DependentValuePath = "Value",
IndependentAxis = new CategoryAxis { Orientation = AxisOrientation.X, ShowGridLines = false, Location = AxisLocation.Bottom},
DependentRangeAxis = new LinearAxis(){Orientation = AxisOrientation.Y, ShowGridLines = false}
};
var labelStyle = new Style(typeof(AxisLabel));
labelStyle.Setters.Add(new Setter(AxisLabel.StringFormatProperty, "{}{0:C0}"));
var axis = (LinearAxis)columnSeries.DependentRangeAxis;
axis.AxisLabelStyle = labelStyle;

In my WPF4 version of the charting toolkit, your code crashes. I needed to change:
labelStyle.Setters.Add(new Setter(AxisLabel.StringFormatProperty, "{}{0:C0}"));
to:
labelStyle.Setters.Add(new Setter(AxisLabel.StringFormatProperty, "{0:C0}"));
That is, remove the {}. The {} comes from markup extension syntax:
{} Escape Sequence / Markup Extension
and is only needed when being parsed by XAML as a markup extension inside "{...}".
Since you are setting the property directly, no markup extension is involved and including it prevents the real currency format from being seen.

Related

Convert MaterialDesignColors.MaterialDesignColor to SolidColorBrush?

I am using this MaterialDesign library in my C# WPF application.
How can I programatically get the HEX color ID for example from the color MaterialDesignColors.MaterialDesignColor.LightBlue500 and then convert it to a SolidColorBrush?
In general, you can get any MaterialDesignColor using the SwatchHelper.
var lightBlue500Color = SwatchHelper.Lookup[MaterialDesignColor.LightBlue500];
You can also get it directly from the corresponding swatch, here LightBlueSwatch.
var lightBlue500Color = LightBlueSwatch.LightBlue500;
var lightBlueSwatch = new LightBlueSwatch();
var lightBlue500Color = lightBlueSwatch.Lookup[MaterialDesignColor.LightBlue500];
From that color, you can create a SolidColorBrush using its constructor.
var lightBlue500SolidColorBrush = new SolidColorBrush(lightBlue500Color);
If you need the hex color string in #AARRGGBB format, you can use the ToString method of Color.
var lightBlue500HexString= LightBlueSwatch.LightBlue500.ToString(); // = "#FF03A9F4"
If you need the #RRGGBB format, you can use a custom format string.
var lightBlue500Color = LightBlueSwatch.LightBlue500;
var lightBlue500HexString = string.Format("#{0:X2}{1:X2}{2:X2}", lightBlue500Color.R, lightBlue500Color.G, lightBlue500Color.B); // = "#03A9F4"
In general, if you want to create a solid color brush from a hex string, you can do this.
var lightBlue500Color = (Color)ColorConverter.ConvertFromString(#FF03A9F4);
var lightBlue500SolidColorBrush = new SolidColorBrush(lightBlue500Color);

Geometry.Combine doesn't work for curves

I want to combine 2 curves like this:
Then here is my code:
// Create a path to draw a geometry with.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
var gmy1 = (StreamGeometry)StreamGeometry.Parse("M100,100C110,118.333333333333 138.333333333333,206.666666666667 160,210 181.666666666667,213.333333333333 205,123.333333333333 230,120 255,116.666666666667 280,186.666666666667 310,190 340,193.333333333333 396.666666666667,156.666666666667 410,140 423.333333333333,123.333333333333 393.333333333333,98.3333333333333 390,90");
var gmy2 = (StreamGeometry)StreamGeometry.Parse("M180,241.25L180,241.25 230,290 300,246.66667175293 330,160");
var gmy = Geometry.Combine(gmy1, gmy2, GeometryCombineMode.Union, null);
myPath.Data = gmy;
// Add path shape to the UI.
this.panel1.Children.Add(myPath);
But the result is this:
How to combine the curves in WPF?
And because of the project limitation, we have to implement this without layout and xaml. That means we need the result type is Geometry.
More general than concatenating path strings:
If you have a set of arbitrary Geometries and want to group them, use a GeometryGroup:
Geometry gmy1 = ...;
Geometry gmy2 = ...;
var gmy = new GeometryGroup();
gmy.Children.Add(gmy1);
gmy.Children.Add(gmy2);
myPath.Data = gmy;
Easy:
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
var gmy1 = (StreamGeometry)StreamGeometry.Parse("M100,100C110,118.333333333333 138.333333333333,206.666666666667 160,210 181.666666666667,213.333333333333 205,123.333333333333 230,120 255,116.666666666667 280,186.666666666667 310,190 340,193.333333333333 396.666666666667,156.666666666667 410,140 423.333333333333,123.333333333333 393.333333333333,98.3333333333333 390,90");
var gmy2 = (StreamGeometry)StreamGeometry.Parse("M180,241.25L180,241.25 230,290 300,246.66667175293 330,160");
var gmy = (StreamGeometry)StreamGeometry.Parse(gmy1.ToString() + gmy2.ToString());
myPath.Data = gmy;
// Add path shape to the UI.
this.panel1.Children.Add(myPath);
The path definition language is a language. Use it as one. StreamGeometry.ToString() unparses a Geometry back to its Path Definition Language representation, which you can then merge with another one.
Note that this works because each starts with a M for Move command: It starts a new line. I don't think there's any realistic case where you'd run into any trouble with that (and it won't let you start with L for Line), but theory's not exactly my strongest subject.
Just add both of them to a Grid or Canvas, Combine does a intersecting combination, you just seem to want to overlay them. Alternatively add both of them to a GeometryGroup and add that to your panel.

How can I set a value for TextBox.FontFamily property?

I am trying to learn WPF, the problem is I need to learn XAML first. In System.Windows.Controls.TextBox class, there is property 'FontFamily'. I will have to set a font for it. In one of my book I saw But where can I get this font(Verdana). Where is list of all font's in MSDN Library?
Ikbal Hassan
You can bind to the string name of the font as shown below as font.Name. The following code is loading up a ComboBox of all the fonts.
var installedfonts = new InstalledFontCollection();
int idFont = 0;
foreach ( var font in installedfonts.Families )
{
var fonttype = new LookupSelectItem { Id = idFont, Name = font.Name };
FontTypeList.Add( fonttype );
++ idFont;
}

Silverlight: DateTime format in TextBlocks

I'd like to use a custom DateTimeFormat across my entire Silverlight app, so I plugged in the following code in my App.xaml.cs.
var ci = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
ci.DateTimeFormat = new DateTimeFormatInfo()
{
ShortDatePattern = "dd/MM/yyyy",
LongDatePattern = "dd/MM/yyyy",
FullDateTimePattern = "dd/MM/yyyy HHmm\\h",
AMDesignator = string.Empty,
PMDesignator = string.Empty,
ShortTimePattern = "HHmm\\h",
LongTimePattern = "HHmm\\h"
};
Thread.CurrentThread.CurrentCulture = ci;
A DateTime.Now.ToString("f") gives me the answer I want (which is a 24-hour format DateTime string). However, when I do the following in XAML, the TextBlock ignores my CultureInfo and does its own thing:
<TextBlock Text="{Binding ArrivalTime,StringFormat=f}"/>
Does anybody know a way in which I can get the TextBlock to display in the format I desire? Many thanks...

How to format specific text in WPF?

I have this code that adds dotted lines under text in text box:
// Create an underline text decoration. Default is underline.
TextDecoration myUnderline = new TextDecoration();
// Create a linear gradient pen for the text decoration.
Pen myPen = new Pen();
myPen.Brush = new LinearGradientBrush(Colors.White, Colors.White, new Point(0, 0.5), new Point(1, 0.5));
myPen.Brush.Opacity = 0.5;
myPen.Thickness = 1.0;
myPen.DashStyle = DashStyles.Dash;
myUnderline.Pen = myPen;
myUnderline.PenThicknessUnit = TextDecorationUnit.FontRecommended;
// Set the underline decoration to a TextDecorationCollection and add it to the text block.
TextDecorationCollection myCollection = new TextDecorationCollection();
myCollection.Add(myUnderline);
PasswordSendMessage.TextDecorations = myCollection;
My problem is I need only the last 6 characters in the text to be formatted!
Any idea how can I achieve that?
Instead of setting the property on the entire TextBlock, create a TextRange for the last six characters and apply the formatting to that:
var end = PasswordSendMessage.ContentEnd;
var start = end.GetPositionAtOffset(-6) ?? PasswordSendMessage.ContentStart;
var range = new TextRange(start, end);
range.ApplyPropertyValue(Inline.TextDecorationsProperty, myCollection);
If PasswordSendMessage is a TextBox rather than a TextBlock, then you cannot use rich text like this. You can use a RichTextBox, in which case this technique will work but you will need to use PasswordSendMessage.Document.ContentEnd and PasswordSendMessage.Document.ContentStart instead of PasswordSendMessage.ContentEnd and PasswordSendMessage.ContentStart.
You could databind your text to the Inlines property of TextBox and make a converter to build the run collection with a seperate Run for the last 6 characters applying your decorations

Resources