如何在内容视图的 Android 应用程序中将开关绑定到 Xamarin 中的 属性?
How do I bind a switch to a property in Xamarin in an Android app in a content view?
我正在使用 Xamarin 在 VS 2022 中创建我的第一个 Android 应用程序,现在我必须将一个开关绑定到一个标签以向用户显示 on/off 的含义。多次所以我做了一个内容视图:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:App1.Controls" x:DataType="controls:SwitchWithText"
x:Class="App1.Controls.SwitchWithText"
x:Name="root">
<ContentView.Content>
<StackLayout Orientation="Horizontal">
<Label x:Name="isOkLbl" Text="is not ok" Margin="10"/>
<Switch x:Name="switch1" IsToggled="{Binding Path=IsToggled}"/>
</StackLayout>
</ContentView.Content>
</ContentView>
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App1.Controls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SwitchWithText : ContentView
{
public static readonly BindableProperty isToggledProperty = BindableProperty.Create(
nameof(isToggledProperty), //name of property
typeof(bool), //type of property
typeof(SwitchWithText), //type of owning object
defaultValue: false,
propertyChanged: IsToggledChanged);
public bool IsToggled
{
get => (bool)GetValue(isToggledProperty);
set => SetValue(isToggledProperty, value);
}
private static void IsToggledChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (SwitchWithText)bindable;
if (control != null && control.switch1.IsToggled)
{
control.isOkLbl.Text = "is ok";
}
else
{
control.isOkLbl.Text = "is not ok";
}
}
public SwitchWithText()
{
BindingContext = this;
InitializeComponent();
}
}
}
有些东西会在 Visual Studio 2022 年自动完成,看起来它会做我需要的,但当我切换开关时没有任何反应。 :(
还是有更好的方法来做到这一点?我看到了带有文字的开关图片,但在 Xamarin 中找不到类似的东西。
这是您想要的结果吗?
我认为您可能想要的是一个值转换器 class,它将采用 IsToggled
绑定并将其转换为标签的字符串。如果您想查看功能演示,我 post 在 GitHub 上编辑了工作代码。 (我将它直接放在 xaml 中用于 ContentPage
,但当然同样的原理也适用于 ContentView
和你的 post。)
using System;
using System.Globalization;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = this;
InitializeComponent();
}
bool _IsToggled = false;
public bool IsToggled
{
get => _IsToggled;
set
{
if (_IsToggled != value)
{
_IsToggled = value;
OnPropertyChanged(nameof(IsToggled));
}
}
}
}
/// <summary>
/// Value converter class
/// </summary>
public class BoolToTextConverter : IValueConverter
{
public string IfFalse { get; set; }
public string IfTrue { get; set; }
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((bool)value)
{
return IfTrue;
}
else
{
return IfFalse;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
然后要使用值转换器,您可以在 xaml 中将其设为静态资源,如下所示:
<?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:app1="clr-namespace:App1"
x:Class="App1.MainPage">
<ContentPage.Resources>
<app1:BoolToTextConverter x:Key="SwitchToText"
IfTrue="is ok"
IfFalse="is not ok" />
</ContentPage.Resources>
<StackLayout>
<Label Text="{Binding Path=IsToggled, Converter={StaticResource SwitchToText}}" FontSize="Title" Padding="30,10,30,10"/>
<Switch x:Name="switch1"
IsToggled="{Binding Path=IsToggled}" />
</StackLayout>
</ContentPage>
所以我的建议是尝试使用值转换器来执行您想要的操作。
我正在使用 Xamarin 在 VS 2022 中创建我的第一个 Android 应用程序,现在我必须将一个开关绑定到一个标签以向用户显示 on/off 的含义。多次所以我做了一个内容视图:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:App1.Controls" x:DataType="controls:SwitchWithText"
x:Class="App1.Controls.SwitchWithText"
x:Name="root">
<ContentView.Content>
<StackLayout Orientation="Horizontal">
<Label x:Name="isOkLbl" Text="is not ok" Margin="10"/>
<Switch x:Name="switch1" IsToggled="{Binding Path=IsToggled}"/>
</StackLayout>
</ContentView.Content>
</ContentView>
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App1.Controls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SwitchWithText : ContentView
{
public static readonly BindableProperty isToggledProperty = BindableProperty.Create(
nameof(isToggledProperty), //name of property
typeof(bool), //type of property
typeof(SwitchWithText), //type of owning object
defaultValue: false,
propertyChanged: IsToggledChanged);
public bool IsToggled
{
get => (bool)GetValue(isToggledProperty);
set => SetValue(isToggledProperty, value);
}
private static void IsToggledChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (SwitchWithText)bindable;
if (control != null && control.switch1.IsToggled)
{
control.isOkLbl.Text = "is ok";
}
else
{
control.isOkLbl.Text = "is not ok";
}
}
public SwitchWithText()
{
BindingContext = this;
InitializeComponent();
}
}
}
有些东西会在 Visual Studio 2022 年自动完成,看起来它会做我需要的,但当我切换开关时没有任何反应。 :( 还是有更好的方法来做到这一点?我看到了带有文字的开关图片,但在 Xamarin 中找不到类似的东西。
这是您想要的结果吗?
我认为您可能想要的是一个值转换器 class,它将采用 IsToggled
绑定并将其转换为标签的字符串。如果您想查看功能演示,我 post 在 GitHub 上编辑了工作代码。 (我将它直接放在 xaml 中用于 ContentPage
,但当然同样的原理也适用于 ContentView
和你的 post。)
using System;
using System.Globalization;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
BindingContext = this;
InitializeComponent();
}
bool _IsToggled = false;
public bool IsToggled
{
get => _IsToggled;
set
{
if (_IsToggled != value)
{
_IsToggled = value;
OnPropertyChanged(nameof(IsToggled));
}
}
}
}
/// <summary>
/// Value converter class
/// </summary>
public class BoolToTextConverter : IValueConverter
{
public string IfFalse { get; set; }
public string IfTrue { get; set; }
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((bool)value)
{
return IfTrue;
}
else
{
return IfFalse;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
然后要使用值转换器,您可以在 xaml 中将其设为静态资源,如下所示:
<?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:app1="clr-namespace:App1"
x:Class="App1.MainPage">
<ContentPage.Resources>
<app1:BoolToTextConverter x:Key="SwitchToText"
IfTrue="is ok"
IfFalse="is not ok" />
</ContentPage.Resources>
<StackLayout>
<Label Text="{Binding Path=IsToggled, Converter={StaticResource SwitchToText}}" FontSize="Title" Padding="30,10,30,10"/>
<Switch x:Name="switch1"
IsToggled="{Binding Path=IsToggled}" />
</StackLayout>
</ContentPage>
所以我的建议是尝试使用值转换器来执行您想要的操作。