Toto
Toto

Reputation: 970

Binding slider ValueChanged event with Xamarin.Forms

I have a slider on a page, and I am trying to implement a step so that the slider only allows integer values.

In order to achieve that, I am trying to associate an event handler to the ValueChanged event. Here is my XAML code:

<Slider ValueChanged="OnSliderValueChanged" Maximum="5" Minimum="1" Value="{Binding MaxProductsToOffer}"/>

And my event handler:

public void OnSliderValueChanged(object sender, EventArgs e)

I get the following compilation error:

Position 15:21. EventHandler "OnSliderValueChanged" not found in type "MyApp.Views.SettingsPage"

What am I missing?

Upvotes: 1

Views: 4368

Answers (3)

EvZ
EvZ

Reputation: 12169

Position 15:21. EventHandler "OnSliderValueChanged" not found in type "MyApp.Views.SettingsPage"

Means that you don't have an EvenHandler with the name "OnSliderValueChanged" on MyApp.Views.SettingsPage. Where it should be since you pointing to it in XAML -> ValueChanged="OnSliderValueChanged". So either define it in your page or remove it from XAML.

Regarding your problem, since you are using bindings Value="{Binding MaxProductsToOffer}" I assume that you are following the MVVM pattern in your project and that you have a dedicated ViewModel bound to MyApp.Views.SettingsPage. If so you all you have to do is to bind Slider.Value to an integer property in your ViewModel that will automatically handle the conversion for you. Here is a solution that does not require any code behind:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:SliderTest"
    x:Class="SliderTest.MyPage"
    Padding="50">
    <ContentPage.BindingContext>
        <local:MainViewModel />
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout>
        <Slider x:Name="slider" Maximum="5" Minimum="1" Value="{Binding SliderValue}" />
        <Label Text="{Binding Source={x:Reference Name=slider}, Path=Value}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
    </StackLayout>
    </ContentPage.Content>
</ContentPage>

public class MainViewModel : INotifyPropertyChanged
{
    int sliderValue;
    public int SliderValue
    {
        get => sliderValue;
        set
        {
            sliderValue = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Alternatively you could: extend Slider and use a private EventHandler to manipulate the value or use an EventHandler in your page. Code example can be found here. However I find it as an overkill compare to my original proposal.

P.S.: If you are using MVVM prefer solutions that does not involve writing code in the UI layer unless it is really necessary.

Upvotes: 0

Johannes
Johannes

Reputation: 958

A slider in Xamarin Forms has explicit ValueChangedEventArgs so your event handler should look like this

public void OnSliderValueChanged(object sender, ValueChangedEventArgs e)

https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.slider.valuechanged?view=xamarin-forms

Upvotes: 1

random
random

Reputation: 487

Add the method:

void OnSliderValueChanged(object sender, EventArgs e)
{
...
}

Add it in code behind. You do not need your event handled.

Upvotes: 0

Related Questions