I am trying to make clickable Icon which will be using for Wish List, for this I have created boolean property which will return Image.
This is my code, but it does not support onClick event, Please advise to figure out this problem.
public class WishIconImg : Image, IDisposable
{
static FontImageSource unselected_source = new FontImageSource();
static FontImageSource selected_source = new FontImageSource();
public WishIconImg()
{
unselected_source.FontFamily = "FA-S";
unselected_source.Glyph = "\U000f02d5";
unselected_source.Color = Color.DarkOrange;
selected_source.FontFamily = "FA-S";
selected_source.Glyph = "\U000f02d1";
selected_source.Color = Color.DarkOrange;
OnClick += Checkbox_OnClick;
}
public static BindableProperty IsCheckedProperty = BindableProperty.Create(
nameof(IsChecked), typeof(bool), typeof(WishIconImg), defaultBindingMode: BindingMode.TwoWay,
propertyChanged: IsCheckedChanged);
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
private static void IsCheckedChanged(BindableObject bindable, object oldValue, object newValue)
{
var cb = (WishIconImg)bindable;
if (cb == null)
return;
if ((bool)newValue)
{
cb.Source = selected_source;
}
else
{
cb.Source=unselected_source ;
}
}
void Checkbox_OnClick(object sender, EventArgs e)
{
IsChecked = !IsChecked;
}
public void Dispose()
{
OnClick -= Checkbox_OnClick;
}
}
}
Xaml
<controls:WishIconImg x:Name="HeartChk" IsChecked="{Binding AddWish, Mode=TwoWay}" HeightRequest="35" WidthRequest="35" HorizontalOptions="End"/>
Even I have tried with Label property but it doesnt work
You could modify the class like following
public WishIconImg()
{
unselected_source.FontFamily = "FA-S";
unselected_source.Glyph = "\U000f02d5";
unselected_source.Color = Color.DarkOrange;
selected_source.FontFamily = "FA-S";
selected_source.Glyph = "\U000f02d1";
selected_source.Color = Color.DarkOrange;
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => {
// handle the tap
IsChecked = !IsChecked;
};
this.GestureRecognizers.Add(tapGestureRecognizer);
}
Try adding TapGestureRecognizer for an click event
Do something like this
<StackLayout HeightRequest="35" WidthRequest="35" HorizontalOptions="End">
<controls:WishIconImg x:Name="HeartChk" IsChecked="{Binding AddWish, Mode=TwoWay}" />
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Checkbox_OnClick}" />
</StackLayout.GestureRecognizers>
</StackLayout>
In your ViewModel Bind the command for it
public System.Windows.Input.ICommand Checkbox_OnClick => new Xamarin.Forms.Command(Checkbox_OnClickTapped);
Checkbox_OnClickTapped will be your method called when your view will be clicked
Related
I have 15 options on my home page. Initially, I will show 9 options in UI. To view the remaining 6 icons, the user slides to the right and back to the left to see previous. I try to implement the swiping feature like below, but it is not working.
XAML
<StackLayout x:Name="firstLlayout">
<Grid>
//3 icons in horizontal
</Grid>
<Grid>
//3 icons in horizontal
</Grid>
<Grid>
//3 icons in horizontal
</Grid>
<StackLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Right" Swiped="RightSwipe"/>
</StackLayout.GestureRecognizers>
</StackLayout>
<StackLayout IsVisible="False" x:Name="secondLayout">
<Grid>
//3 icons in horizontal
</Grid>
<Grid>
//3 icons in horizontal
</Grid>
<StackLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Swiped="LeftSwipe"/>
</StackLayout.GestureRecognizers>
</StackLayout>
XAML.CS
public void RightSwipe(object sender, EventArgs e)
{
firstLlayout.IsVisible = false;
secondLayout.IsVisible = true;
}
public void LeftSwipe(object sender, EventArgs e)
{
secondLayout.IsVisible = false;
firstLlayout.IsVisible = true;
}
When try left and right swipe nothing is happening in UI, and code execution not coming to event functions. What I am missing here?
Cause1:
Swipe action will conflict with scroll action if you put the stacklayout in a ScrollView .
Solution:
Remove the ScrollView from Root StackLayout, then the swiping will work.
Cause2: It is necessary to add a child control(like Image or Label)to StackLayout , otherwise the swipe action will never been called .
Solution: If you do want to let the content of StackLayout shows nothing in default, you can check the following code .
in code behind
using System;
using Xamarin.Forms;
namespace xxx
{
public class GestureScrollView : ScrollView
{
public event EventHandler SwipeLeft;
public event EventHandler SwipeRight;
public void OnSwipeLeft() =>
SwipeLeft?.Invoke(this, null);
public void OnSwipeRight() =>
SwipeRight?.Invoke(this, null);
}
}
in Android Project
using System;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using xxx;
using xxx.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(GestureScrollView), typeof(GestureScrollViewRenderer))]
namespace xxx.Droid
{
public class GestureScrollViewRenderer : ScrollViewRenderer
{
readonly CustomGestureListener _listener;
readonly GestureDetector _detector;
public GestureScrollViewRenderer(Context context) : base(context)
{
_listener = new CustomGestureListener();
_detector = new GestureDetector(context, _listener);
}
public override bool DispatchTouchEvent(MotionEvent e)
{
if (_detector != null)
{
_detector.OnTouchEvent(e);
base.DispatchTouchEvent(e);
return true;
}
return base.DispatchTouchEvent(e);
}
public override bool OnTouchEvent(MotionEvent ev)
{
base.OnTouchEvent(ev);
if (_detector != null)
return _detector.OnTouchEvent(ev);
return false;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
{
_listener.OnSwipeLeft -= HandleOnSwipeLeft;
_listener.OnSwipeRight -= HandleOnSwipeRight;
}
if (e.OldElement == null)
{
_listener.OnSwipeLeft += HandleOnSwipeLeft;
_listener.OnSwipeRight += HandleOnSwipeRight;
}
}
void HandleOnSwipeLeft(object sender, EventArgs e) =>
((GestureScrollView)Element).OnSwipeLeft();
void HandleOnSwipeRight(object sender, EventArgs e) =>
((GestureScrollView)Element).OnSwipeRight();
}
public class CustomGestureListener : GestureDetector.SimpleOnGestureListener
{
static readonly int SWIPE_THRESHOLD = 100;
static readonly int SWIPE_VELOCITY_THRESHOLD = 100;
MotionEvent mLastOnDownEvent;
public event EventHandler OnSwipeLeft;
public event EventHandler OnSwipeRight;
public override bool OnDown(MotionEvent e)
{
mLastOnDownEvent = e;
return true;
}
public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if (e1 == null)
e1 = mLastOnDownEvent;
float diffY = e2.GetY() - e1.GetY();
float diffX = e2.GetX() - e1.GetX();
if (Math.Abs(diffX) > Math.Abs(diffY))
{
if (Math.Abs(diffX) > SWIPE_THRESHOLD && Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
OnSwipeRight?.Invoke(this, null);
else
OnSwipeLeft?.Invoke(this, null);
}
}
return base.OnFling(e1, e2, velocityX, velocityY);
}
}
}
And in Xaml
Put the StackLayout in the ScrollView
<local:GestureScrollView SwipeRight="RightSwipe">
<StackLayout x:Name="firstLlayout" >
//...
</StackLayout>
</local:GestureScrollView>
I like and used Lucas Zhang's answer answer-59190549 to this question however, the GestureScrollView can be changed to utilize the same GestureRecognizer's that iOS will use like so:
public class GestureScrollView : ScrollView
{
private bool isInitialized = false;
private List<SwipeGestureRecognizer> LeftSwipeRecognizers { get; } = new();
private List<SwipeGestureRecognizer> RightSwipeRecognizers { get; } = new();
public GestureScrollView() : base()
{
}
protected override void LayoutChildren(double x, double y, double width, double height)
{
base.LayoutChildren(x, y, width, height);
//Not sure if this is the best place, but the ctor wasn't getting called.
if (!isInitialized)
{
isInitialized = true;
foreach (SwipeGestureRecognizer swipeGestureRecognizer in GestureRecognizers.Where(x => x is SwipeGestureRecognizer))
{
if (swipeGestureRecognizer.Direction.HasFlag(SwipeDirection.Left))
{
LeftSwipeRecognizers.Add(swipeGestureRecognizer);
}
if (swipeGestureRecognizer.Direction.HasFlag(SwipeDirection.Right))
{
RightSwipeRecognizers.Add(swipeGestureRecognizer);
}
}
}
}
private void ExecuteGestureCommands(List<SwipeGestureRecognizer> swipeRecognizers, SwipedEventArgs e)
{
foreach (var gesture in swipeRecognizers)
{
gesture.SendSwiped(this, e.Direction);
}
}
public void OnSwipeLeft(object sender, SwipedEventArgs e)
{
ExecuteGestureCommands(LeftSwipeRecognizers, e);
}
public void OnSwipeRight(object sender, SwipedEventArgs e)
{
ExecuteGestureCommands(RightSwipeRecognizers, e);
}
}
And the Renderer would need changes similar to these (Basically change all "EventArgs" references to "SwipedEventArgs" and pass in a new SwipedEventArgs on the event calls):
...
void HandleOnSwipeLeft(object sender, SwipedEventArgs e) => ((GestureScrollView)Element).OnSwipeLeft(sender, e);
void HandleOnSwipeRight(object sender, SwipedEventArgs e) => ((GestureScrollView)Element).OnSwipeRight(sender, e);
...
public event EventHandler<SwipedEventArgs> OnSwipeLeft;
public event EventHandler<SwipedEventArgs> OnSwipeRight;
...
if (diffX > 0)
{
OnSwipeRight?.Invoke(this, new SwipedEventArgs(null, SwipeDirection.Right));
}
else
{
OnSwipeLeft?.Invoke(this, new SwipedEventArgs(null, SwipeDirection.Left));
}
...
It's not perfect as it ignores the Up/Down directions in Android, but so does the other implementation.
I am being trying to use the flexlayout and it's great but now for each item in the stack layout i need to add tapped gesturer,command etc..
Whatever I try does not work.The only thing that works is the stacklayout.TapGestureRecognizer but as soon as I try to use the command does not work.
I even tried the https://taubensee.net/adding-touch-events-to-flexlayouts/
and added a commandparameter bindable property but does not work either.
How do you add a command with commandparameter to flexlayout .below is my code
<FlexLayout BindableLayout.ItemsSource="{Binding Customers}"
AlignContent="Start"
AlignItems="Start"
Direction="Row"
JustifyContent="Start"
Wrap="Wrap">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout
FlexLayout.AlignSelf="Start"
FlexLayout.Basis="50%">
<!--<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
</StackLayout.GestureRecognizers>-->
<Frame>
<!--<Frame.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ItemTappedCommand}"
CommandParameter="{Binding .}" />
</Frame.GestureRecognizers>-->
<StackLayout>
<Label Text="whatever"></Label>
<!--<Image Source="myimage.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ItemTappedCommand}" CommandParameter="AAAA"
NumberOfTapsRequired="1"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>-->
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
<!--<FlexLayout.Behaviors>
<behaviors:FlexLayoutItemTappedBehavior
Command="{Binding ItemTappedCommand2}" CommandParameter="{Binding .}"/>
</FlexLayout.Behaviors>-->
</FlexLayout>
FlexLayout maybe miss the touch events and commands , have a try with Behavior to realize it.
Create a new class that inherits from Behavior<T>:
public class FlexLayoutItemTappedBehavior : Behavior<FlexLayout>
{
public static readonly BindableProperty CommandProperty =
BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);
public static readonly BindableProperty ParamaterProperty =
BindableProperty.Create(nameof(Paramater), typeof(object), typeof(FlexLayoutItemTappedBehavior), defaultBindingMode: BindingMode.OneWay);
public ICommand Command
{
get => (ICommand)this.GetValue(CommandProperty);
set => this.SetValue(CommandProperty, value);
}
public object Paramater
{
get => (object)this.GetValue(ParamaterProperty);
set => this.SetValue(ParamaterProperty, value);
}
protected override void OnAttachedTo(FlexLayout bindable)
{
base.OnAttachedTo(bindable);
if (bindable.BindingContext != null)
{
this.BindingContext = bindable.BindingContext;
}
bindable.BindingContextChanged += this.OnFlexLayoutBindingChanged;
bindable.ChildAdded += this.OnFlexLayoutChildAdded;
}
protected override void OnDetachingFrom(FlexLayout bindable)
{
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= this.OnFlexLayoutBindingChanged;
bindable.ChildAdded -= this.OnFlexLayoutChildAdded;
foreach (var child in bindable.Children)
{
if (child is View childView && childView.GestureRecognizers.Any())
{
var tappedGestureRecognizers = childView.GestureRecognizers.Where(x => x is TapGestureRecognizer).Cast<TapGestureRecognizer>();
foreach (var tapGestureRecognizer in tappedGestureRecognizers)
{
tapGestureRecognizer.Tapped -= this.OnItemTapped;
childView.GestureRecognizers.Remove(tapGestureRecognizer);
}
}
}
}
private void OnFlexLayoutBindingChanged(object sender, EventArgs e)
{
if (sender is FlexLayout flexLayout)
{
this.BindingContext = flexLayout.BindingContext;
}
}
private void OnFlexLayoutChildAdded(object sender, ElementEventArgs args)
{
if (args.Element is View view)
{
var tappedGestureRecognizer = new TapGestureRecognizer();
tappedGestureRecognizer.Tapped += this.OnItemTapped;
view.GestureRecognizers.Add(tappedGestureRecognizer);
}
}
private async void OnItemTapped(object sender, EventArgs e)
{
if (sender is VisualElement visualElement)
{
var animations = new List<AnimationBase>();
var scaleIn = new ScaleToAnimation
{
Target = visualElement,
Scale = .95,
Duration = "50"
};
animations.Add(scaleIn);
var scaleOut = new ScaleToAnimation
{
Target = visualElement,
Scale = 1,
Duration = "50"
};
animations.Add(scaleOut);
var storyBoard = new StoryBoard(animations);
await storyBoard.Begin();
}
if (sender is BindableObject bindable && this.Command != null && this.Command.CanExecute(null))
{
object resolvedParameter;
if (Paramater != null)
{
resolvedParameter = Paramater;
}
else
{
resolvedParameter = e;
}
if (Command.CanExecute(resolvedParameter))
{
this.Command.Execute(bindable.BindingContext);
}
}
}
}
Lastly, in order to use this Behavior from XAML, you can reference it like this:
<FlexLayout.Behaviors>
<behaviors:FlexLayoutItemTappedBehavior
Command="{Binding NavigateToDetailCommand}" Paramater="{Binding .}"/>
</FlexLayout.Behaviors>
About Reusable EventToCommandBehavior , you can refer to here .
On an Xamarian.Forms app, which is trying to redirect links that contain a PDF in from a WebView to a Google Drive URL. My code works as expected on iOS but just spins on an Android.
public partial class Balance : ContentPage
{
public Balance()
{
InitializeComponent();
website.Navigated += WebView_Navigated;
website.Navigating += WebView_Navigating;
UrlWebViewSource source = new UrlWebViewSource();
source.Url = "https://www.google.com";
website.Source = source;
}
private void WebView_Navigating(object sender, WebNavigatingEventArgs e)
{
progress.IsVisible = true;
website.IsVisible = false;
}
public void WebView_Navigated(object sender, WebNavigatedEventArgs e)
{
progress.IsVisible = false;
website.IsVisible = true;
if (e.Url.Contains("pdf") && !e.Url.Contains("drive.google.com"))
{
var webview = (WebView)sender;
website.Source = "https://drive.google.com/viewerng/viewer?embedded=true&url=" + e.Url;
}
}
}
On Android the site never loads and the activity indicator just sits and spins.
According to your description, I use your code and redirect a webview, here is my code, there is no issue on android, nospins on android :
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="website"
HeightRequest="1000"
Navigated="Website_Navigated"
Navigating="Website_Navigating"
WidthRequest="1000" />
</StackLayout>
</ContentPage.Content>
public partial class Page19 : ContentPage
{
public Page19 ()
{
InitializeComponent ();
UrlWebViewSource source = new UrlWebViewSource();
//source.Url = "https://www.google.com";
source.Url = "http://www.pdf995.com/samples/pdf.pdf";
website.Source = source;
}
private void Website_Navigated(object sender, WebNavigatedEventArgs e)
{
website.IsVisible = false;
}
private void Website_Navigating(object sender, WebNavigatingEventArgs e)
{
website.IsVisible = true;
if (e.Url.Contains("pdf") && !e.Url.Contains("drive.google.com"))
{
var webview = (WebView)sender;
website.Source = "https://drive.google.com/viewerng/viewer?embedded=true&url=" + e.Url;
}
}
}
I am trying to make a custom stepper to use in my listview such as this one
Any idea how to do this? Thanks.
Solution 1:
A Stepper allows inputting a discrete value that is constrained to a range. You could display the value of the Stepper using data binding in a label as follows :
Define in XAML:
<StackLayout x:Name="Container">
<Label BindingContext="{x:Reference stepper}" Text="{Binding Value}" />
<Stepper Minimum="0" Maximum="10" x:Name="stepper" Increment="0.5" />
</StackLayout>
Solution 2:
You could create a BindableProperty to implement this function, for example:
public class CustomStepper : StackLayout
{
Button PlusBtn;
Button MinusBtn;
Entry Entry;
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
propertyName: "Text",
returnType: typeof(int),
declaringType: typeof(CustomStepper),
defaultValue: 1,
defaultBindingMode: BindingMode.TwoWay);
public int Text
{
get { return (int)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public CustomStepper()
{
PlusBtn = new Button { Text = "+", WidthRequest = 40, FontAttributes = FontAttributes.Bold, FontSize = 15 };
MinusBtn = new Button { Text = "-", WidthRequest = 40, FontAttributes = FontAttributes.Bold, FontSize = 15 };
switch (Device.RuntimePlatform)
{
case Device.UWP:
case Device.Android:
{
PlusBtn.BackgroundColor = Color.Transparent;
MinusBtn.BackgroundColor = Color.Transparent;
break;
}
case Device.iOS:
{
PlusBtn.BackgroundColor = Color.DarkGray;
MinusBtn.BackgroundColor = Color.DarkGray;
break;
}
}
Orientation = StackOrientation.Horizontal;
PlusBtn.Clicked += PlusBtn_Clicked;
MinusBtn.Clicked += MinusBtn_Clicked;
Entry = new Entry
{
PlaceholderColor = Color.Gray,
Keyboard = Keyboard.Numeric,
WidthRequest = 40, BackgroundColor = Color.FromHex("#3FFF")
};
Entry.SetBinding(Entry.TextProperty, new Binding(nameof(Text), BindingMode.TwoWay, source: this));
Entry.TextChanged += Entry_TextChanged;
Children.Add(PlusBtn);
Children.Add(Entry);
Children.Add(MinusBtn);
}
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewTextValue))
this.Text = int.Parse(e.NewTextValue);
}
private void MinusBtn_Clicked(object sender, EventArgs e)
{
if (Text > 1)
Text--;
}
private void PlusBtn_Clicked(object sender, EventArgs e)
{
Text++;
}
}
For more detailed information, please refer to the following documents:
Stepper in Xamarin Forms
Stepper Control In Xamarin.Forms Application For Android And UWP
C# (CSharp) Xamarin.Forms.Stepper Code Examples
Xamarin Forms Guide -- Stepper
Update:
In the CustomStepper class, the Entry value is binding with the Text property, so you could get the value of the entry via customStepper.Text.
For example:
<local:CustomStepper x:Name="MyCustomerStepper"/>
You could get its Entry value in your xaml.cs file via:
var yourCustomerStepperEntryValue = MyCustomerStepper.Text.ToString();
I implemented this CustomStepper:
using System;
using Xamarin.Forms;
namespace AppXamarin
{
public class CustomStepper : StackLayout
{
Button PlusBtn;
Button MinusBtn;
Entry Entry;
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
propertyName: "Text",
returnType: typeof(int),
declaringType: typeof(CustomStepper),
defaultValue: 0,
defaultBindingMode: BindingMode.TwoWay);
public int Text
{
get { return (int)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public CustomStepper()
{
PlusBtn = new Button { WidthRequest = 30, HeightRequest = 30 };
MinusBtn = new Button { WidthRequest = 30, HeightRequest = 30 };
PlusBtn.Image = "exp20181029Artboard51";
MinusBtn.Image = "exp20181029Artboard52";
switch (Device.RuntimePlatform)
{
case Device.UWP:
case Device.Android:
{
PlusBtn.BackgroundColor = Color.Transparent;
MinusBtn.BackgroundColor = Color.Transparent;
break;
}
case Device.iOS:
{
PlusBtn.BackgroundColor = Color.Transparent;
MinusBtn.BackgroundColor = Color.Transparent;
break;
}
}
Orientation = StackOrientation.Horizontal;
PlusBtn.Clicked += PlusBtn_Clicked;
MinusBtn.Clicked += MinusBtn_Clicked;
Entry = new Entry { PlaceholderColor = Color.Gray, Keyboard = Keyboard.Numeric, WidthRequest = 30, BackgroundColor = Color.Transparent, FontSize = 15 };
Entry.Keyboard = Keyboard.Numeric;
Entry.Behaviors.Add(new NumericValidationBehavior());
Entry.SetBinding(Entry.TextProperty, new Binding(nameof(Text), BindingMode.TwoWay, source: this));
Entry.HorizontalTextAlignment = TextAlignment.Center;
Entry.TextChanged += Entry_TextChanged;
Children.Add(MinusBtn);
Children.Add(Entry);
Children.Add(PlusBtn);
}
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewTextValue) && e.NewTextValue != ".")
this.Text = int.Parse(e.NewTextValue);
}
private void MinusBtn_Clicked(object sender, EventArgs e)
{
if (Text > 0)
Text--;
}
private void PlusBtn_Clicked(object sender, EventArgs e)
{
Text++;
}
}
}
When placing normally in the page I can access it and take the text property and use it in my Xaml.cs code. But in my case, I'm placing it inside a listview and as you know in listview the items are bindable I can't access it directly. In the regular stepper when it is placed in the listview we can use the "ValueChanged" method and can easily get the value by using e.NewValue in the "ValueChanged" method in the Xaml.cs file. Is there a way that I can add something to the CustomStepper class that can help me access the Text property and uses it in the Xaml.cs file? Thanks in advance
You can create a property for EventHandlers. In this case, you would use the event modifier on the property to tell the program that the property is triggering an event. For example:
private EventHandler onValueChangedEvent = null;
public event EventHandler OnValueChanged
{
add
{
onValueChangedEvent = null;
onValueChangedEvent = value;
}
remove
{
// Will show a warning. You can ignore it.
onValueChangedEvent = null;
}
}
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewTextValue) && e.NewTextValue != ".")
this.Text = int.Parse(e.NewTextValue);
onValueChangedEvent?.Invoke(this, e);
}
You would then bind/assign an event handler in your xaml.cs code to the OnValueChanged property, which will get triggered when the value changes.