Archive
Difference between LocalizableAttribute and LocalizabilityAttribute in .NET
I’ve just updated an older answer of mine at:
In case you’re wondering too what’s the difference between Localizable and Localizability attributes in .NET, maybe this helps a bit:
https://msdn.microsoft.com/en-us/library/ms753944(v=vs.100).aspx
- LocalizableAttribute – Specifies whether a property should be localized
- LocalizabilityAttribute – Specifies the localization attributes for a binary XAML (BAML) class or class member
Seems the Localizability attribute is BAML-specific and makes sure localization-related comments (probably to make use by localization tools and show to the translators) are preserved/exposed when WPF XAML is compiled from text XML form into binary BAML.
Gotcha: WPF UserControl SizeChanged event not firing at resizing
Useful to know:
If you set the Width and Height on the UserControl though, you have set a fixed size and thus even if its parent tool window changes size, the UserControl never will. You should not set Width and Height on the UserControl if you want that event to be raised as the parent tool window changes size.
from:
http://www.actiprosoftware.com/community/thread/20365/size-change-event-for-the-usercontrol
HowTo: List all known color names and find name of given color at WPF
This is my answer at
http://stackoverflow.com/questions/4475391/wpf-silverlight-find-the-name-of-a-color
Modified answer from Thomas Levesque to populate the Dictionary only when 1st needed, instead of taking the cost at startup (going to use at speech recognition-driven turtle graphics, so that user can pronounce known color names to change the turtle’s pen color)
- //Project: SpeechTurtle (http://SpeechTurtle.codeplex.com)
- //Filename: ColorUtils.cs
- //Version: 20150901
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Windows.Media;
- namespace SpeechTurtle.Utils
- {
- /// <summary>
- /// Color-related utility methods
- /// </summary>
- public static class ColorUtils //based on http://stackoverflow.com/questions/4475391/wpf-silverlight-find-the-name-of-a-color
- {
- #region — Fields —
- private static Dictionary<string, Color> knownColors; //=null
- #endregion
- #region — Methods —
- #region Extension methods
- public static string GetKnownColorName(this Color color)
- {
- return GetKnownColors()
- .Where(kvp => kvp.Value.Equals(color))
- .Select(kvp => kvp.Key)
- .FirstOrDefault();
- }
- public static Color GetKnownColor(this string name)
- {
- Color color;
- return GetKnownColors().TryGetValue(name, out color) ? color : Colors.Black; //if color for name is not found, return black
- }
- #endregion
- public static Dictionary<string, Color> GetKnownColors()
- {
- if (knownColors == null)
- {
- var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
- knownColors = colorProperties.ToDictionary(
- p => p.Name,
- p => (Color)p.GetValue(null, null));
- }
- return knownColors;
- }
- public static string[] GetKnownColorNames()
- {
- return GetKnownColors().Keys.ToArray();
- }
- #endregion
- }
- }
HowTo: Insert new line and spacing at content of WPF TextBlock control
While adding more voice commands at SpeechTurtle, I had to update the active legend where the available commands are displayed and their text is highlighted as the respective commands are recognized by the speech recognition engine (using .NET’s managed Speech API).
A problem I faced was how to add a newline and prefixing the 2nd line with some spaces to align with the first command at the 1st line…
First of all, adding a new line was easy, inserted a <LineBreak /> tag in the XAML inside the TextBlock tag’s content, as shown in the screenshot below:
Then I had the issue that I needed to add some spacing so that “Pen up” at the 2nd line starts exactly under the start of “Forward” at the 1st line (see screenshot above)…
Tried to add a Run tag, with its Text set to some spaces, but couldn’t get an exact positioning:
So I tried using a Separator instead, since I could define a Width for it, however, it was drawing as a gray line:
So I either had to change its color to White or Transparent, or use a Null Foreground Brush on it (one difference of a Null brush from a Transparent one is that the element ignores Mouse events in that case from what I remember), or just set its Visibility mode to Hidden:
Do note that WPF has another visibility mode apart from Visible and Hidden, that is Collapsed, where the respective control disappears from the layout flow (that value is not supported in Silverlight from what I remember), which is not what we wanted in this case (Hidden was the correct option to choose):
Managed .NET Speech API links
(this is my answer at http://stackoverflow.com/questions/14771474/voice-recognition-in-windows)
I’m looking into adding speech recognition to my fork of Hotspotizer Kinect-based app (http://github.com/birbilis/hotspotizer)
After some search I see you can’t markup the actionable UI elements with related speech commands in order to simulate user actions on them as one would expect if Speech input was integrated in WPF. I’m thinking of making a XAML markup extension to do that, unless someone can point to pre-existing work on this that I could reuse…
The following links should be useful:
http://www.wpf-tutorial.com/audio-video/speech-recognition-making-wpf-listen/
http://www.c-sharpcorner.com/uploadfile/mahesh/programming-speech-in-wpf-speech-recognition/
https://msdn.microsoft.com/en-us/library/hh855387.aspx (make use of Kinect mic array audio input)
http://kin-educate.blogspot.gr/2012/06/speech-recognition-for-kinect-easy-way.html
https://channel9.msdn.com/Series/KinectQuickstart/Audio-Fundamentals
https://www.microsoft.com/en-us/download/details.aspx?id=27225
https://www.microsoft.com/en-us/download/details.aspx?id=27226
http://www.redmondpie.com/speech-recognition-in-a-c-wpf-application/
http://www.codeproject.com/Articles/55383/A-WPF-Voice-Commanded-Database-Management-Applicat
http://www.codeproject.com/Articles/483347/Speech-recognition-speech-to-text-text-to-speech-a
http://www.c-sharpcorner.com/uploadfile/nipuntomar/speech-to-text-in-wpf/
http://www.w3.org/TR/speech-grammar/
https://msdn.microsoft.com/en-us/library/hh361625(v=office.14).aspx
HowTo: use PivotViewer in WPF
PivotViewer is an impressive Silverlight control (see my usage at http://gallery.clipflair.net), however Microsoft never released it for WPF.
One could work arround this by embedding Silverlight in their WPF app using the WebBrowser control and talking to it via the JavaScript Bridge of Silverlight, however they could also embed one of those HTML5 PivotViewer-compatible controls that have surfaced in recent years.
Apart from LobsterPot’s HTML5 PivotViewer and its older free version, for another HTML5 PivotViewer (and also a DeepZoom implementation for HTML5) you could host that comes from former SeaDragon team members at Microsoft and seems to work very well see:
https://github.com/seajax/seajax/tree/master/v2/app/pivot
https://github.com/seajax/seajax/blob/master/v2/app/pivot/quickstart.html
https://github.com/seajax/seajax
Note that the WebBrowser control uses IE7 or something as HTML engine by default and you need some meta markup at the top of your HTML to tell it to use Edge mode – the latest IE engine that is installed)
<meta http-equiv="X-UA-Compatible" content="IE=edge">
HowTo: Make Project Linker extension’s VSIX install at Visual Studio 2012
Project Linker is a Visual Studio Extension that “helps to automatically create and maintain links from a source project to a target project to share code that is common to Silverlight and WPF”.
In ClipFlair, where I have shared code between a Silverlight and a WPF project (I guess same would be for XNA projects for Xbox360 and for PC), a practice I use is to put shared files in a “Source” project and add them to both projects as links (using “Open as link” action available from Add file dialog if you press the dropdown arrow next to the “Open” button).
An alternative is to put such files in say the WPF project and use the Project Linker tool from Microsoft Patterns & Practices group to link to those files from the Silverlight project easily.
However, that tool seems to be only available for Visual Studio 2010, not for the newer 2012 version. Luckily, some users have posted a workarround at the discussion there (Reviews and Q&A tabs):
- Download the .vsix
- Extract contents with 7-Zip (since .vsix is a .zip file which you can see by renaming to .zip or .vsix.zip)
- Modify file with extension .vsixmanifest to add <visualstudio version="11.0"> to the <supportedproducts> node
- Change MaxVersion to <supportedframeworkruntimeedition minversion="3.5" maxversion="4.5" /> (this may not be necessary)
- Zip up contents again
- Rename extension back to .vsix
- Install extension
According to comments there, this works but not for all project types. It works if one links the Silverlight project to the WPF one, but not the other way around. It throws a NullReferenceException somewhere in the extension.
HowTo: Clear contents of Silverlight’s RichTextBox control
Was just debugging an issue with loading of saved state at ClipFlair’s Text component, when I realized that Silverlight’s (and WPF’s) RichTextBox control doesn’t accept an empty string at its Xaml proprerty to clear its contents as one would expect. Instead clearing the contents of the RichTextBox requires a call to Blocks.Clear().
In ClipFlair’s case, the Text component (a FloatingWindow descendent) hosts a SilverTextEditor control, which in turn hosts a RichTextBox named rtb and has its own Xaml property, where I added the needed logic to clear the RichTextBox contents when getting a null or empty string. Wonder why Microsoft couldn’t do the same thing.
public string Xaml {
get { return rtb.Xaml; }
set {
if (value != null && value.Trim() != "") rtb.Xaml = value;
else rtb.Blocks.Clear();
} //allows to set null or blank value to clear the RichTextBox
}
HowTo: Scale control arround its center using a render transform
In the context of ClipFlair development, I was recently adding independent scaling (zooming) functionality to its ZUI container’s floating windows (apart from the container zooming functionality) and came across some strange behavior, where the windows seemed to also move apart from getting scaled.
After banging my head a bit I decided to take a closer look at Microsoft’s documentation and noticed the following text at http://msdn.microsoft.com/en-us/library/system.windows.uielement.rendertransformorigin.aspx
"RenderTransformOrigin has a somewhat nonstandard use of the Point structure value, in that the Point does not represent an absolute location in a coordinate system. Instead, values between 0 and 1 are interpreted as a factor for the range of the current element in each x,y axis. For example, (0.5,0.5) will cause the render transform to be centered on the element, or (1,1) would place the render transform at the bottom right corner of the element. NaN is not an accepted value. Values beyond 0 and 1 are also accepted, and will result in more unconventional transform effects. For instance, if you set RenderTransformOrigin to be (5,5), and then apply a RotateTransform, the rotation point will be well outside the bounds of the element itself. The transform will spin your element around in a big circle that originates beyond bottom right. The origin might be somewhere inside its parent element and could possibly be possibly out of frame or view. Negative point values are similar, these will go beyond the top left bounds. Render transforms do not affect layout, and are typically used to animate or apply a temporary effect to an element."
Since ClipFlair’s FloatingWindowHostZUI template uses a Canvas to host its FloatingWindows, I obviously didn’t care about the phrase “Render transforms do not affect layout”, but the phrase “values between 0 and 1 are interpreted as a factor for the range of the current element in each x,y axis” rang a bell immediately.
Misguided by the poor Intellisense info for the RenderTransformOrigin property, I had thought that point was in the control’s coordinate system, and since I wanted to scale the control arround its center, I had used the following erroneous statement:
window.RenderTransformOrigin = new Point(window.ActualWidth/2, window.ActualHeight/2);
window.RenderTransform = new ScaleTransform().SetScale((double)e.NewValue);
…
instead of the correct one:
window.RenderTransformOrigin = new Point(0.5, 0.5);
//scale arround the window center
window.RenderTransform = new ScaleTransform().SetScale((double)e.NewValue);
That is the range 0 to 1 for x & y coordinates of RenderTransformOrigin refers to the UIElement region, whereas less or greater values are (proportionally) outside of it, useful for example if you want to rotate an object arround an external point with a RotateTransform.
Don’t get puzzled by the expression new ScaleTransform().SetScale(…), it’s a syntax I use for authoring portable source code between WPF and Silverlight (since Silverlight only has a parameter-less constructor for ScaleTransform and anyway WPF doesn’t have a constructor that takes a single parameter for both X and Y scale values).
To sum up, here’s the “Scale” property I added to the FloatingWindow class:
#region public double Scale
/// <summary> /// Gets or sets current window scale. /// </summary> /// <value>Current scale.</value>
public double Scale {
get { return (double)GetValue(ScaleProperty); }
set { SetValue(ScaleProperty, value); } } /// <summary>
/// Identifies the <see cref="FloatingWindow.Scale" /> dependency property.
/// </summary>
/// <value>
/// The identifier for the <see cref="FloatingWindow.Scale" /> dependency property.
/// </value> public static readonly DependencyProperty ScaleProperty =
DependencyProperty.Register("Scale", typeof(double), typeof(FloatingWindow),
new PropertyMetadata(1d, OnScalePropertyChanged));
//Must use 1d here, not 1 (else will get XAMLParseException at runtime)
/// <summary>
/// ScaleProperty PropertyChangedCallback call back static function.
/// </summary>
/// <param name="d">FloatingWindow object whose Scale property is changed.</param>
/// <param name="e">DependencyPropertyChangedEventArgs contains old and new values.</param> private static void OnScalePropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e) {
FloatingWindow window = (FloatingWindow)d;
if (window != null)
{
window.RenderTransformOrigin = new Point(0.5, 0.5); //scale arround the window center
window.RenderTransform = new ScaleTransform().SetScale((double)e.NewValue);
}
} #endregion