Name: uwp-reusables
Owner: Futurice
Description: A library of controls and logic that get reused frequently.
Created: 2016-01-18 15:54:59.0
Updated: 2016-03-08 13:46:37.0
Pushed: 2016-06-16 13:20:37.0
Size: 118
Language: C#
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
A collection of logic and controls that are generically useful for any UWP project.
Current status: Not ready for release
What needs to be done?
A text box that validates all input, and displays error messages if any of the validation functions fail.
Can be used in XAML:
tb:ValidatingTextBox PlaceholderText="No dots or exclamations allowed.">
<vtb:ValidationPair ErrorMessage="No dots allowed." ValidationFunction="{x:Bind NoDotsFunction}"/>
<vtb:ValidationPair ErrorMessage="Exclamation marks not allowed either >:|" ValidationFunction="{x:Bind NoExclamationsFunction}"/>
tb:ValidatingTextBox>
and the validation functions bound to are simply defined in code-behind as follows:
ic Func<string, bool> NoDotsFunction { get; set; } = NoDotsFunctionImpl;
ic Func<string, bool> NoExclamationsFunction { get; set; } = NoExclamationsImpl;
ate static bool NoDotsFunctionImpl(string input)
if (input.Contains("."))
{
return false;
}
else
{
return true;
}
ate static bool NoExclamationsImpl(string arg)
if (arg.Contains("!"))
{
return false;
}
else
{
return true;
}
Note that the validation functions are pure, static functions, and could be defined anywhere; your ViewModel, a PCL, whatever.
Can also be defined in code-behind:
ng locallyScopedString = "closures work just fine";
datingTextBox codeBehindBox = new ValidatingTextBox();
BehindBox.ValidationPairs.Add(new ValidationPair
ValidationFunction = s => s.Contains("@"),
ErrorMessage = $"Gotta have at least one @ here. And {locallyScopedString}!",
The portable version of the above ValidatingTextBox. This sacrifices usability in favor of portability. The ValidatingTextBox requires that any part of the program that defines validation functions know about the ValidationPair class, and requires a reference to the ValidatingTextBox project. The ValidatingTextBoxPortable, however, allows validating functions to be defined without needing that reference. The tradeoff is that the syntax is slightly less friendly.
In XAML:
idation:ValidatingTextBoxPortable PlaceholderText="No dots or exclamations"
ValidationFunctions="{x:Bind TopBoxValidationFunctions}">
And the TopBoxValidationFunctions
is an IList<Func<string, string>>
–that is, a List of Functions that take in a string as input, and return a string. It might be defined as follows:
ic IList<Func<string, string>> TopBoxValidationFunctions => new List<Func<string, string>>
input => input.Contains("!") ? "No shouting! Exclamations aren't allowed." : null,
input => input.Contains(".") ? "Can't be having none of them dots, either." : null
…and those validation functions treat null
return values as validation successes, and non-null values are treated as validation failures, with the returned string being interpreted as the error message for that validation function.
The InlineFormatter
attached propertes allow binding formatted text strings (e.g. "<format>This <bold>text</bold> <underline>has</underline> <italic>formatting</italic>!</format>"
) as XAML TextBlock
content. The feature is implemented by parsing the input string using the platform XML parser and assigning the resulting Inline
tree to TextBlock.Inlines
.
You might be asking what is the point of such behaviour: in XAML, we can always anyway construct the corresponding Inline tree in code and directly assign it to the target TextBlock. Well, this might be a good idea as long as you never have to localize your app. However, as soon as you start sourcing your UI strings from a localization file, you will most definitely want to specify the logical structure of the formatting in your translated strings. This is not possible by using vanilla bindings, because you can't do anything like <TextBlock Inlines="{x:Bind MyLocalizedFormatString}" />
(<TextBlock Text="{x:Bind MyLocalizedSimpleString}" />
works, because Text
expects a string).
The formatting can be anything supported by XAML Inlines, and you can define your own custom formatter in code, including adding inline links with arbirtrary click handlers. The default formatter only supports mapping the Bold, Underline and Italic tags 1:1. See the TestBed for examples.
This code was inspired by and improved from http://stackoverflow.com/questions/5565885/how-to-bind-a-textblock-to-a-resource-containing-formatted-text