Xamarin.Forms Entry with auto thousand and decimal separator - xamarin

I have a Xamarin.Forms entry with numeric keyboard that will represent a pt-BR REAL currency (999.999,99). When I type numbers in the numeric keyboard, the comma(representing decimal) and dot(representind thousand) needs to be added automatically while I am typing.
To achieve this goal, what is the best practice/design pattern in Xamarin.Forms to work in all platforms?

The trick is to use a TextChanged event. The first step I removed the $ from the string so that I could parse the new text value. If it fails to parse, that means that the user added a non-digit character and we just revert to whatever the old text was.
Next, we detect if user ADDED a new digit and its to the RIGHT of the decimal (example 1.532). If so we, we move the decimal to the right by * 10. Do the opposite for a DELETION.
OH, and almost forgot about when we initialize the number! The first digit we enter will be a whole number so we * 100 to make sure the first digit we enter starts as fraction.
Once we got our decimal correct, we display it using num.ToString("C");
Working Example:
xaml:
<Entry
Keyboard="Numeric"
TextChanged="OnFinancialTextChanged"
Placeholder="$10.00"
Text="{Binding RetailPrice}"/>
Then in the cs
.cs:
private void OnFinancialTextChanged(object sender, TextChangedEventArgs e)
{
var entry = (Entry)sender;
var amt = e.NewTextValue.Replace("$", "");
if (decimal.TryParse(amt, out decimal num))
{
// Init our number
if(string.IsNullOrEmpty(e.OldTextValue))
{
num = num / 100;
}
// Shift decimal to right if added a decimal digit
else if (num.DecimalDigits() > 2 && !e.IsDeletion())
{
num = num * 10;
}
// Shift decimal to left if deleted a decimal digit
else if(num.DecimalDigits() < 2 && e.IsDeletion())
{
num = num / 10;
}
entry.Text = num.ToString("C");
}
else
{
entry.Text = e.OldTextValue;
}
}
I created these Extension methods to help with the logic
public static class ExtensionMethods
{
public static int DecimalDigits(this decimal n)
{
return n.ToString(System.Globalization.CultureInfo.InvariantCulture)
.SkipWhile(c => c != '.')
.Skip(1)
.Count();
}
public static bool IsDeletion(this TextChangedEventArgs e)
{
return !string.IsNullOrEmpty(e.OldTextValue) && e.OldTextValue.Length > e.NewTextValue.Length;
}
}

No need to create a custom renderer.
I recommend to subclass Entry and subscribe to the TextChanged event.
In there you would parse and reformat the current text and update the Text property.

Related

xamarin convert entry text to numeric value

I'm new user of Xamarin studio 5.9.5 (build 9) on Windows, and I want make a form based application that involves some mathematical calculations (.Net + Gtk#).
I made a simple form containing 3 Entry widgets (2 for input values and 1 for output value) and 1 button. Here is the code for the button (simple addition Entry3 = Entry1 + Entry2)
using System;
using Gtk;
...
protected void OnBtnClicked (object sender, EventArgs e)
{
entry3.Text = entry1.Text + entry2.Text;
//throw new NotImplementedException ();
}
As you can see, this code just makes a concatenation of both text fields.
How can I convert the text fields into numeric values in order to achieve mathematical addition (and other calculations) ?
Thanks
// assuming these values are ints
int val1 = int.Parse(entry1.Text);
int val2 = int.Parse(entry2.Text);
entry3.Text = val1 + val2;

Movement Position Being Equal to Int

I wasn't exactly sure how to title this, however I will explain what I mean. I am trying to make my game object move using:
transform.translate(Vector2.up \* moveSpeed * time.deltaTime);
Now what I want to do next is what is causing some trouble. I would like the object to continue moving until it hits the Y value of 1, and then turn left. I almost have that working. See it WILL work if I use >= 1, because it skips over the value of 1 (not moving by choppy ints). Even if I try changing it to == 1.0f it still won't work as I guess the object is moving too quickly and skips over some values. We've tried re-positioning it in the >= block of code but that bugs out and doesn't work very well.
If you have any thoughts or possible solutions that would be great! Thanks! :-D
Code ex:
if (transform.position.x <= -2 && transform.position.y < -1) {
transform.Translate(Vector2.up * playerSpeed * Time.deltaTime);
}
else if (transform.position.y <= -4)
{
transform.Translate(Vector2.left * playerSpeed * Time.deltaTime);
}
I can't really match what you want from your gif. Although, what you need is fairly simple when you think of adding a bool value called didCollidHappen and implement the OnCollideEnter method in your script.
Doing so, when you call Update at each frame, you will verify if there were any collisions and then call the code to make your game object jump. What follows is a code snippet. Insert it in your C# script :-)
public bool didCollideHappen =false;
public void OnCollideEnter(Collision col)
{
if(col.gameObject.tag == "Something")//if it's any game object, then just put bool value to true !!
{
didCollidedHappen = true;
}
}
public void MakeSlowedJump()
{
actualSpeed -= slowAmount * Time.fixedDeltaTime;
transform.position += new Vector3 (0.13F, actualSpeed * Time.fixedDeltaTime, 0);
}
public void Update()
{
if(didCollideHappen)
MakeSlowedJump();
}

Formatting Numberfield and making it sortable in javafx Tableview

I have Column in tableview which is a Decimal. If I format it have thousand separator, the sorting happens as if it is a text. Appreciate if anyone can share an example code which keeps that column as number and sorts too as number.
Thanks
Jay
I figured, this is the way to solve the problem.
colName.setComparator(new Comparator<String>(){
#Override
public int compare(String t, String t1) {
try{
DecimalFormat df = new DecimalFormat("#,###,##0.00");
Double d1 =df.parse(t);
Double d2 = df.parse(t1);
return Double.compare(d1,d2);
}catch(ParseException p){
p.printStackTrace();
}
return -1;
}

Select hyphenated word with double-click

UPDATE: Per the recommendation below, here's specifically what I'd like to do: If I double-click the mouse cursor anywhere from the "b" to the "n" of "blue-green", I want all of the word "blue-green" should be highlighted. How can this be done? Currently, depending on where you click, it treats "blue-green" as three separate character strings. So, if you double click between the "b" and "e" of "blue" it highlights only "blue" and not "-green." If you double-click the hyphen, it highlights the hyphen alone. And if you double-click between the "g" and "n" of "green" it highlights only "green" and not "blue-".
ORIGINAL: When I double-click a hyphenated word or set of characters (e.g. "123-abc" or "blue-green" etc.), only the part of the word that I double-clicked is highlighted. I'd like the whole word to be highlighted.
I'm using Windows 7 Pro. If it needs to be done on a per-application basis, I'm most interested in fixing it for Google Chrome, but any Windows-compatible web browser would be OK.
Old question, but I happen to have been working on the same issue. Here's my solution:
jsFiddle.net
"use strict"
// Tweak to make a double-click select words with hyphens
//
// As of 2016-0816, None of the major Mac browser selects whole words
// with hyphens, like "ad-lib". This tweak fixes the hypen issue.
//
// Note: Firefox 48.0 doesn't automatically select whole words with
// apostrophes like "doesn't". This tweak also treats that.
;(function selectWholeWordsWithHyphens(){
var pOutput = document.getElementById("output")
var selection = window.getSelection()
// Regex designed to find a word+hyphen before the selected word.
// Example: ad-|lib|
// It finds the last chunk with no non-word characters (except for
// ' and -) before the first selected character.
var startRegex = /(\w+'?-?)+-$/g
// Regex designed to find a hyphen+word after the selected word.
// Example: |ad|-lib
var endRegex = /^-('?-?\w+)+/
// Edge case: check if the selection contains no word
// characters. If so, then don't do anything to extend it.
var edgeRegex = /\w/
document.body.ondblclick = selectHyphenatedWords
function selectHyphenatedWords(event) {
if (!selection.rangeCount) {
return
}
var range = selection.getRangeAt(0)
var container = range.startContainer
var string = container.textContent
var selectionUpdated = false
if (string.substring(range.startOffset, range.endOffset)
.search(edgeRegex) < 0) {
// There are no word characters selected
return
}
extendSelectionBackBeforeHypen(string, range.startOffset)
extendSelectionForwardAfterHyphen(string, range.endOffset)
if (selectionUpdated) {
selection.removeAllRanges()
selection.addRange(range)
}
function extendSelectionBackBeforeHypen(string, offset) {
var lastIndex = 0
var result
, index
string = string.substring(0, offset)
while (result = startRegex.exec(string)) {
index = result.index
lastIndex = startRegex.lastIndex
}
if (lastIndex === offset) {
range.setStart(container, index)
selectionUpdated = true
}
}
function extendSelectionForwardAfterHyphen(string, offset) {
if (!offset) {
return
}
string = string.substring(offset)
var result = endRegex.exec(string)
if (result) {
range.setEnd(container, offset + result[0].length)
selectionUpdated = true
}
}
}
})()
It's a standard through all programs that it will do that because they all run off the operating system's typing configuration/program thing. To fix it you would need to do something in System32. I don't know what you would need to do but I suspect this is your problem. You should probably go into more detail though about specifically what it is you want.

An array stack algorithm without copy

I have a flashlite3 application with navigation consisting of icons the user can browse left or right through infinitely.
The basic algorithm i'm using now works (and is adequate for this project) however, part of the solution depends on a duplicate of the array of icons. Depending on the number of items in the array, and/or the size of the element contents, this solution could become less efficient. I'm interested in a solution or algorithm(in any language) that could achieve the same thing while being scalable & efficient.
Heres a portion of relevant code in the setter function for mutating the '_selectedItem' property, which:
Evaluates the current '_selectedItem' and the new '_value'
Based on step 1 pop,unshifts right, or shift,pops left
Repeats step 2 until the icon matching the '_selectedItem' is in the center of the array
This code runs using 3 arrays:
[static] Array of positions. There are 5 icons, 3 are visible at a time, so position 0 is off stage, position 1 is 1/3, position 2 is 1/2 ..
When instantiating the icons 2 arrays are created: _viewArray & _icons. The order of _viewArray mimics the order to be displayed and _icons is left alone and used for the loop condition checking
///Actionscript2///
public function set selectedItem(value:Number)
{
var w=Stage.width;
if(value > _icons.length-1)
{
value=0;
}else if(value < 0)
{
value=_icons.length-1;
}
if(value > _selectedIndex)
{
while(_viewArray[Math.floor(_icons.length*.5)] != _icons[value])
{
var element;
element=_viewArray.pop();
_viewArray.unshift(element);
}
}else if(value < _selectedIndex)
{
while(_viewArray[Math.floor(_icons.length*.5)]!=_icons[value])
{
var element;
element=_viewArray.shift();
_viewArray.push(element);
}
}
for(var i:Number=0;i<_viewArray.length;i++)
{
if(i>=1 && i<= _icons.length-2)
{
_viewArray[i]._visible=true;
}else
{
_viewArray[i]._visible=false;
}
Tweener.addTween(_viewArray[i],{_x:positions[i],_alpha:80,time:.5,transition:'elasticIn'})
}
Tweener.addTween(_icons[(_viewArray.length*.5)-1],{_alpha:100,time:.0,transition:'elasticIn'});
Tweener.addTween(_selectedServiceIndicator,{_alpha:0,time:.3,transition:'elasticIn',onComplete:function() {Tweener.addTween(this,{_alpha:100,time:.2,transition:'elasticIn'});}});
var eventObject:Object = {target:this, type:'SelectedItemChange'};
eventObject.value=value;
for(var key in _serviceData[value])
eventObject[key]=_serviceData[value][key];
dispatchEvent(eventObject);
_selectedIndex=value;
}
Why does each element of the _viewArray has to actually store the icon, rather than only the index into the _icons array? This way you only have the icons stored once, and _viewArray just stores their presentation order.

Resources