C# 使用Xamarin.Forms绑定滑块值更改事件

C# 使用Xamarin.Forms绑定滑块值更改事件,c#,xaml,xamarin,xamarin.forms,binding,C#,Xaml,Xamarin,Xamarin.forms,Binding,我在页面上有一个滑块,我正在尝试实现一个步骤,以便滑块只允许整数值 为了实现这一点,我尝试将事件处理程序与ValueChanged事件关联起来。以下是我的XAML代码: <Slider ValueChanged="OnSliderValueChanged" Maximum="5" Minimum="1" Value="{Binding MaxProductsToOffer}"/> 我发现以下编译错误: 位置15:21。在类型中找不到EventHandler“OnSliderValu

我在页面上有一个滑块,我正在尝试实现一个步骤,以便滑块只允许整数值

为了实现这一点,我尝试将事件处理程序与ValueChanged事件关联起来。以下是我的XAML代码:

<Slider ValueChanged="OnSliderValueChanged" Maximum="5" Minimum="1" Value="{Binding MaxProductsToOffer}"/>
我发现以下编译错误:

位置15:21。在类型中找不到EventHandler“OnSliderValueChanged” “MyApp.Views.SettingsPage”

我缺少什么?

添加方法:

void OnSliderValueChanged(object sender, EventArgs e)
{
...
}
将其添加到代码隐藏中。
您不需要处理事件。

Xamarin表单中的滑块具有显式的
值changedEventArgs
,因此您的事件处理程序应该如下所示

public void OnSliderValueChanged(object sender, ValueChangedEventArgs e)

位置15:21。在类型中找不到EventHandler“OnSliderValueChanged” “MyApp.Views.SettingsPage”

意味着在
MyApp.Views.SettingsPage
上没有名为“OnSliderValueChanged”的
EvenHandler
。它应该在哪里,因为您在XAML中指向它->
ValueChanged=“OnSliderValueChanged”
。 因此,要么在页面中定义它,要么从XAML中删除它

关于您的问题,由于您使用的是绑定
Value=“{Binding MaxProductsToOffer}”
我假设您在项目中遵循MVVM模式,并且您有一个专用的
ViewModel
绑定到
MyApp.Views.SettingsPage
。如果是这样,您只需将
Slider.Value
绑定到
ViewModel
中的整数属性,该属性将自动为您处理转换。以下是一个不需要任何代码隐藏的解决方案:

<?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));
    }
}

公共类MainViewModel:INotifyPropertyChanged
{
int-sliderValue;
公共int SliderValue
{
get=>sliderValue;
设置
{
sliderValue=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
void OnPropertyChanged([CallerMemberName]字符串propertyName=”“)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
或者,您可以:扩展
滑块
,并使用私有EventHandler来操作值,或者在页面中使用EventHandler。可以找到代码示例。然而,与我最初的提议相比,我觉得这是一种过分的做法

注意:如果您使用的是MVVM,那么您更喜欢不涉及在UI层编写代码的解决方案,除非确实有必要

<?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));
    }
}