简体   繁体   English

如何在 Xaml 文件的 Xamarin.Forms 中添加复选框?

[英]How to add Checkbox in Xamarin.Forms in Xaml file?

I'm completely new to xamarin.forms, I need to add a checkbox, radio buttons and drop down list.我是 xamarin.forms 的新手,我需要添加一个复选框、单选按钮和下拉列表。 I tried some samples from net but I'm not able to get the checkbox.我尝试了一些来自网络的样本,但我无法获得复选框。 Can anyone help me to achieve this in xamarin.forms?任何人都可以帮助我在 xamarin.forms 中实现这一目标吗?

Xaml file Xaml 文件

<toolkit:CheckBox Text ="Employee"
                  FontSize="20"
                  CheckedChanged ="OnClicked"/>

or或者

<controls:CheckBox DefaultText="Default text"
                               HorizontalOptions="FillAndExpand"
                               TextColor="Green"
                               FontSize="25"
                               FontName="AmericanTypewriter"/>

Some links or sample code will make it easier to understand.一些链接或示例代码将使其更易于理解。

I found a better way to do this which is to create your own.我找到了一个更好的方法来做到这一点,那就是创建你自己的。 It was really quite simple.这真的很简单。 Create a cs file in a Resources project (or where ever you want) called CheckBox and paste this code:在资源项目(或您想要的任何地方)中创建一个名为 CheckBox 的 cs 文件并粘贴以下代码:

namespace Resources.Controls
{

public class Checkbox : Button 
{
    public Checkbox()
    {
        base.Image = "Image_Unchecked.png";
        base.Clicked += new EventHandler(OnClicked);
        base.SizeChanged += new EventHandler(OnSizeChanged);
        base.BackgroundColor = Color.Transparent;
        base.BorderWidth = 0;
    }

    private void OnSizeChanged(object sender, EventArgs e)
    {
        //if (base.Height > 0)
        //{
        //    base.WidthRequest = base.Height;
        //}
    }

    public static BindableProperty CheckedProperty = BindableProperty.Create(
        propertyName: "Checked",
        returnType: typeof(Boolean?),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: CheckedValueChanged);

    public Boolean? Checked
    {
        get
        {
            if (GetValue(CheckedProperty) == null)
            {
                return null;
            }
            return (Boolean)GetValue(CheckedProperty);
        }
        set
        {
            SetValue(CheckedProperty, value);
            OnPropertyChanged();
            RaiseCheckedChanged();
        }
    }

    private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (newValue != null && (Boolean)newValue == true)
        {
            ((Checkbox)bindable).Image = "Image_Checked.png";
        }
        else
        {
            ((Checkbox)bindable).Image = "Image_Unchecked.png";
        }
    }

    public event EventHandler CheckedChanged;
    private void RaiseCheckedChanged()
    {
        if (CheckedChanged != null)
            CheckedChanged(this, EventArgs.Empty);
    }

    private Boolean _IsEnabled = true;
    public Boolean IsEnabled
    {
        get
        {
            return _IsEnabled;
        }
        set
        {
            _IsEnabled = value;
            OnPropertyChanged();
            if (value == true)
            {
                this.Opacity = 1;
            }
            else
            {
                this.Opacity = .5;
            }
            base.IsEnabled = value;
        }
    }

    public void OnEnabled_Changed()
    {

    }

    public void OnClicked(object sender, EventArgs e)
    {
        Checked = !Checked;

        // Call the base class event invocation method.
        //base.Clicked(sender, e);
    }

}
}

There is probably a better way to do this but I just added the two images to the appropriate locations in each project (base for UWP, Resources/Drawable for Android).可能有更好的方法来做到这一点,但我只是将这两个图像添加到每个项目中的适当位置(UWP 的基础,Android 的资源/Drawable)。

在此处输入图片说明

Then to use it in your Xaml just do something like this (I used a converter bc I was binding to a string value):然后在您的 Xaml 中使用它,只需执行以下操作(我使用了转换器 bc 我绑定到了一个字符串值):

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Resources.Controls;assembly=Resources"
             x:Class="MyNameSpace.CheckBoxExamplePage"
             Title=" Hygiene">
  <Grid Padding="1">
    <ScrollView Padding="4">
      <StackLayout>
        <StackLayout Orientation="Horizontal">
          <controls:Checkbox x:Name="cbHello" Text="Hello CheckBox" Checked="{Binding Path=My.Binding.Path, Converter={StaticResource StringToBoolean}, Mode=TwoWay}" />
        </StackLayout>
        <StackLayout Orientation="Horizontal" Padding="16,0,0,0">
          <controls:Checkbox x:Name="cbDisabled" Text="Disabled Example" IsEnabled="False" Checked="{Binding Path=My.Binding.PathTwo, Converter={StaticResource StringToBoolean}, Mode=TwoWay}" />
        </StackLayout>
      </StackLayout>
    </ScrollView>
  </Grid>
</ContentPage>

Note: You must set the BindingContext in your pages cs file for the check to work.注意:您必须在页面 cs 文件中设置 BindingContext 才能进行检查。 So your Pages code behind file should look like this:所以你的页面代码隐藏文件应该是这样的:

namespace MyNameSpace
{
    public partial class CheckBoxExamplePage
    {
        public CheckBoxExamplePage(object MyBindingObject)
        {
            InitializeComponent();

            this.BindingContext = MyBindingObject;
        }
    }
}

And this is the result!这就是结果!

在此处输入图片说明

Hope this helps someone!!希望这对某人有帮助!!

UPDATE:更新:

The following is new code that removes the gray background on disabled and also allows text to wrap if it does not fit on the screen.以下是删除禁用的灰色背景的新代码,如果文本不适合屏幕,还允许文本换行。 This uses a ContentView that contains a grid that can expand based on the content.这使用了一个 ContentView,它包含一个可以根据内容展开的网格。

    public class Checkbox : ContentView
{
    protected Grid ContentGrid;
    protected ContentView ContentContainer;
    public Label TextContainer;
    protected Image ImageContainer;

    public Checkbox()
    {
        var TapGesture = new TapGestureRecognizer();
        TapGesture.Tapped += TapGestureOnTapped;
        GestureRecognizers.Add(TapGesture);

        ContentGrid = new Grid
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand
        };

        ContentGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(42) });
        ContentGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        ContentGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });

        ImageContainer = new Image
        {
            VerticalOptions = LayoutOptions.Center,
            HorizontalOptions = LayoutOptions.Center,
        };
        ImageContainer.HeightRequest = 42;
        ImageContainer.WidthRequest = 42;

        ContentGrid.Children.Add(ImageContainer);

        ContentContainer = new ContentView
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
        };
        Grid.SetColumn(ContentContainer, 1);

        TextContainer = new Label
        {
            TextColor = Color.White,
            VerticalOptions = LayoutOptions.Center,
            HorizontalOptions = LayoutOptions.FillAndExpand,
        };
        ContentContainer.Content = TextContainer;

        ContentGrid.Children.Add(ContentContainer);

        base.Content = ContentGrid;

        this.Image.Source = "Image_Unchecked.png";
        this.BackgroundColor = Color.Transparent;
    }

    public static BindableProperty CheckedProperty = BindableProperty.Create(
        propertyName: "Checked",
        returnType: typeof(Boolean?),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: CheckedValueChanged);

    public static BindableProperty TextProperty = BindableProperty.Create(
        propertyName: "Text",
        returnType: typeof(String),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: TextValueChanged);

    public Boolean? Checked
    {
        get
        {
            if (GetValue(CheckedProperty) == null)
                return null;
            return (Boolean)GetValue(CheckedProperty);
        }
        set
        {
            SetValue(CheckedProperty, value);
            OnPropertyChanged();
            RaiseCheckedChanged();
        }
    }

    private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (newValue != null && (Boolean)newValue == true)
            ((Checkbox)bindable).Image.Source = "Image_Checked.png";
        else
            ((Checkbox)bindable).Image.Source = "Image_Unchecked.png";
    }

    public event EventHandler CheckedChanged;
    private void RaiseCheckedChanged()
    {
        if (CheckedChanged != null)
            CheckedChanged(this, EventArgs.Empty);
    }

    private Boolean _IsEnabled = true;
    public Boolean IsEnabled
    {
        get { return _IsEnabled; }
        set
        {
            _IsEnabled = value;
            OnPropertyChanged();
            this.Opacity = value ? 1 : .5;
            base.IsEnabled = value;
        }
    }

    public event EventHandler Clicked;
    private void TapGestureOnTapped(object sender, EventArgs eventArgs)
    {
        if (IsEnabled)
        {
            Checked = !Checked;
            if (Clicked != null)
                Clicked(this, new EventArgs());
        }
    }

    private static void TextValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ((Checkbox)bindable).TextContainer.Text = (String)newValue;
    }

    public event EventHandler TextChanged;
    private void RaiseTextChanged()
    {
        if (TextChanged != null)
            TextChanged(this, EventArgs.Empty);
    }

    public Image Image
    {
        get { return ImageContainer; }
        set { ImageContainer = value; }
    }

    public String Text
    {
        get { return (String)GetValue(TextProperty); }
        set
        {
            SetValue(TextProperty, value);
            OnPropertyChanged();
            RaiseTextChanged();
        }
    }

}

You need to add the Nuget package called Xlabs.form.您需要添加名为 Xlabs.form 的 Nuget 包。 Try to import it in your Xaml.cs file like:尝试将其导入您的 Xaml.cs 文件中,例如:

using XLabs.Forms.Controls;

In addition, you also have to add the following line in your .cs file:此外,您还必须在 .cs 文件中添加以下行:

CheckBox chk=new CheckBox()
            {
                checked=false;
            };

In Xaml it is different:在 Xaml 中它是不同的:

<CheckBox  x:Name="checked" isSelected="{Binding flag}"/>

Or you can use <controls:checkbox> .或者您可以使用<controls:checkbox>

Note: Don't forget to add the below line in the Contentpage of Xaml:注意:不要忘记在 Xaml 的 Contentpage 中添加以下行:

 xmlns:controls="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"

I implemented the checkbox and dropdown in the .cs file of xamarin cross platform.I suggest you use cs files for creating the UI.Xamarin is providing the leverage to use any one of the feature either cs file or AXML file to create the UI我在 xamarin 跨平台的 .cs 文件中实现了复选框和下拉菜单。我建议您使用 cs 文件来创建 UI。Xamarin 提供了使用 cs 文件或 AXML 文件中的任何一项功能来创建 UI 的杠杆作用

using System;
using Xamarin.Forms;
using XLabs.Forms.Controls;

namespace Facedetection
{
    public class firstPage : ContentPage
    {
        string statename;

        public firstPage ()
        {

            CheckBox checkbox = new CheckBox () {
                TextColor=Color.Blue,
                CheckedText="I am checked"

            };

            Picker statepick = new Picker ();
            statepick.WidthRequest = 300;
            statepick.Title = "Select a state";
            statepick.Items.Add ("India");
            statepick.Items.Add ("US");
            statepick.Items.Add ("Arizona");
            statepick.Items.Add ("China");

            statepick.SelectedIndexChanged += (sender, e) => {
                if (statepick.SelectedIndex == -1) {
                    DisplayAlert ("Title", "Item not selected", "ok");
                } else {
                    statename = statepick.Items [statepick.SelectedIndex];
                    Console.WriteLine ("Selected country is:" + statename);
                }
            };




            Content = new StackLayout { 
                Children = {
                    checkbox,statepick
                }
            };
        }
    }
}




worked for me 

Based on Kasper Answers, but using the image instead of a button so that it will not show the shadow.基于 Kasper Answers,但使用图像而不是按钮,这样它就不会显示阴影。

public class CustomCheckbox : Image
{
    private const string CheckboxUnCheckedImage = "checkbox_unchecked";
    private const string CheckboxCheckedImage = "checkbox_checked";

    public CustomCheckbox()
    {
        Source = CheckboxUnCheckedImage;
        var imageTapGesture = new TapGestureRecognizer();
        imageTapGesture.Tapped += ImageTapGestureOnTapped;
        GestureRecognizers.Add(imageTapGesture);
        PropertyChanged += OnPropertyChanged;
    }

    private void ImageTapGestureOnTapped(object sender, EventArgs eventArgs)
    {
        if (IsEnabled)
        {
            Checked = !Checked;
        }
    }

    /// <summary>
    /// The checked changed event.
    /// </summary>
    public event EventHandler<bool> CheckedChanged;

    /// <summary>
    /// The checked state property.
    /// </summary>
    public static readonly BindableProperty CheckedProperty = BindableProperty.Create("Checked", typeof(bool), typeof(CustomCheckbox), false, BindingMode.TwoWay, propertyChanged: OnCheckedPropertyChanged);

    public bool Checked
    {
        get
        {
            return (bool)GetValue(CheckedProperty);
        }

        set
        {
            if (Checked != value)
            {
                SetValue(CheckedProperty, value);
                CheckedChanged?.Invoke(this, value);
            }
        }
    }

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e?.PropertyName == IsEnabledProperty.PropertyName)
        {
            Opacity = IsEnabled ? 1 : 0.5;
        }
    }

    private static void OnCheckedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var checkBox = bindable as CustomCheckbox;
        if (checkBox != null)
        {
            var value = newValue as bool?;
            checkBox.Checked = value.GetValueOrDefault();
            checkBox.Source = value.GetValueOrDefault() ? CheckboxCheckedImage : CheckboxUnCheckedImage;
        }
    }
}

Since Xamarin.Forms 4.1.0 (shipped Summer 2019) there is a Checkbox built-in!从 Xamarin.Forms 4.1.0(2019 年夏季发货)开始,内置了一个 Checkbox! Preferrably we use this in the future.我们最好在将来使用它。 https://devblogs.microsoft.com/xamarin/checkbox-xamarin-forms-4-1-0-pre-release/ https://devblogs.microsoft.com/xamarin/checkbox-xamarin-forms-4-1-0-pre-release/

Just an example:只是一个例子:

<CheckBox IsChecked="True" IsEnabled="False" HorizontalOptions="End" Margin="0"/>

现在 Xamarin Forms 有自己的 CheckBox。

<CheckBox IsChecked="{Binding IsChecked}"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM