在Xamarin Forms中显示/隐藏复选框

时间:2016-03-10 07:39:00

标签: xamarin xamarin-forms custom-renderer

我正试图找出一种方法,使按钮点击页面上显示复选框。

默认情况下它是不可见的,因为我在自定义渲染器中设置了checkBox.Visibility = Android.Views.ViewStates.Invisible;

我在页面内容中有一个按钮,模板中有一个复选框,位于页面资源中。

从我的ViewModel中,我可以在CheckBox控件中调用PropertyChanged,在那里我可以看到正确设置旧值和新值。

但我需要一种方法在ViewRenderer上设置它。我猜它需要处理类似于CheckedChanged的某种事件。

视图模型

CheckBox c = new CheckBox { IsCheckBoxVisible=true,IsVisible=true };
CheckBox control

public class CheckBox : View
{
    /// <summary>
    /// The checked state property.
    /// </summary>
    public static readonly BindableProperty CheckedProperty =
        BindableProperty.Create<CheckBox, bool>(
            p => p.Checked, false, BindingMode.TwoWay, propertyChanged: OnCheckedPropertyChanged);

    **public static readonly BindableProperty IsCheckBoxVisibleProperty =
    BindableProperty.Create<CheckBox, bool>(
        p => p.IsCheckBoxVisible, false, BindingMode.OneWay, propertyChanged: OnVisibilityPropertyChanged);**

    /// <summary>
    /// The checked text property.
    /// </summary>
    public static readonly BindableProperty CheckedTextProperty =
        BindableProperty.Create<CheckBox, string>(
            p => p.CheckedText, string.Empty, BindingMode.TwoWay);

    /// <summary>
    /// The unchecked text property.
    /// </summary>
    public static readonly BindableProperty UncheckedTextProperty =
        BindableProperty.Create<CheckBox, string>(
            p => p.UncheckedText, string.Empty);

    /// <summary>
    /// The default text property.
    /// </summary>
    public static readonly BindableProperty DefaultTextProperty =
        BindableProperty.Create<CheckBox, string>(
            p => p.Text, string.Empty);

    /// <summary>
    /// Identifies the TextColor bindable property.
    /// </summary>
    /// 
    /// <remarks/>
    public static readonly BindableProperty TextColorProperty =
        BindableProperty.Create<CheckBox, Color>(
            p => p.TextColor, Color.Default);

    /// <summary>
    /// The font size property
    /// </summary>
    public static readonly BindableProperty FontSizeProperty =
        BindableProperty.Create<CheckBox, double>(
            p => p.FontSize, -1);

    /// <summary>
    /// The font name property.
    /// </summary>
    public static readonly BindableProperty FontNameProperty =
        BindableProperty.Create<CheckBox, string>(
            p => p.FontName, string.Empty);


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

    **public event EventHandler<EventArgs<bool>> VisibilityChanged;**

    /// <summary>
    /// Gets or sets a value indicating whether the control is checked.
    /// </summary>
    /// <value>The checked state.</value>
    public bool Checked
    {
        get
        {
            return this.GetValue<bool>(CheckedProperty);
        }

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



    **public bool IsCheckBoxVisible
    {
        get
        {
            return this.GetValue<bool>(IsCheckBoxVisibleProperty);
        }
        set
        {
            if (this.IsCheckBoxVisible != value)
            {
                this.SetValue(IsCheckBoxVisibleProperty, value);
                this.VisibilityChanged.Invoke(this, value);
                //OnPropertyChanged("IsCheckBoxVisible");
            }
        }
    }**

    /// <summary>
    /// Gets or sets a value indicating the checked text.
    /// </summary>
    /// <value>The checked state.</value>
    /// <remarks>
    /// Overwrites the default text property if set when checkbox is checked.
    /// </remarks>
    public string CheckedText
    {
        get
        {
            return this.GetValue<string>(CheckedTextProperty);
        }

        set
        {
            this.SetValue(CheckedTextProperty, value);
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether the control is checked.
    /// </summary>
    /// <value>The checked state.</value>
    /// <remarks>
    /// Overwrites the default text property if set when checkbox is checked.
    /// </remarks>
    public string UncheckedText
    {
        get
        {
            return this.GetValue<string>(UncheckedTextProperty);
        }

        set
        {
            this.SetValue(UncheckedTextProperty, value);
        }
    }

    /// <summary>
    /// Gets or sets the text.
    /// </summary>
    public string DefaultText
    {
        get
        {
            return this.GetValue<string>(DefaultTextProperty);
        }

        set
        {
            this.SetValue(DefaultTextProperty, value);
        }
    }

    /// <summary>
    /// Gets or sets the color of the text.
    /// </summary>
    /// <value>The color of the text.</value>
    public Color TextColor
    {
        get
        {
            return this.GetValue<Color>(TextColorProperty);
        }

        set
        {
            this.SetValue(TextColorProperty, value);
        }
    }

    /// <summary>
    /// Gets or sets the size of the font.
    /// </summary>
    /// <value>The size of the font.</value>
    public double FontSize
    {
        get
        {
            return (double)GetValue(FontSizeProperty);
        }
        set
        {
            SetValue(FontSizeProperty, value);
        }
    }

    /// <summary>
    /// Gets or sets the name of the font.
    /// </summary>
    /// <value>The name of the font.</value>
    public string FontName
    {
        get
        {
            return (string)GetValue(FontNameProperty);
        }
        set
        {
            SetValue(FontNameProperty, value);
        }
    }
    /// <summary>
    /// Gets the text.
    /// </summary>
    /// <value>The text.</value>
    public string Text
    {
        get
        {
            return this.Checked
                ? (string.IsNullOrEmpty(this.CheckedText) ? this.DefaultText : this.CheckedText)
                    : (string.IsNullOrEmpty(this.UncheckedText) ? this.DefaultText : this.UncheckedText);
        }
    }

    /// <summary>
    /// Called when [checked property changed].
    /// </summary>
    /// <param name="bindable">The bindable.</param>
    /// <param name="oldvalue">if set to <c>true</c> [oldvalue].</param>
    /// <param name="newvalue">if set to <c>true</c> [newvalue].</param>
    private static void OnCheckedPropertyChanged(BindableObject bindable, bool oldvalue, bool newvalue)
    {
        var checkBox = (CheckBox)bindable;
        checkBox.Checked = newvalue;
    }

    **private static void OnVisibilityPropertyChanged(BindableObject bindable, bool oldvalue, bool newvalue)
    {
        var checkBox = (CheckBox)bindable;
        checkBox.IsCheckBoxVisible = newvalue;
    }**

}

CheckBoxRenderer

protected override void OnElementChanged(ElementChangedEventArgs e)
{
    base.OnElementChanged(e);

    if (this.Control == null)
    {
        var checkBox = new Android.Widget.CheckBox(this.Context);
        checkBox.Visibility = Android.Views.ViewStates.Invisible;
        checkBox.CheckedChange += CheckBoxCheckedChange;
        defaultTextColor = checkBox.TextColors;
        this.SetNativeControl(checkBox);
    }
    Control.Text = e.NewElement.Text;
    Control.Checked = e.NewElement.Checked;
    UpdateTextColor();
    if (e.NewElement.FontSize > 0)
    {
        Control.TextSize = (float)e.NewElement.FontSize;
    }

    if (!string.IsNullOrEmpty(e.NewElement.FontName))
    {
        Control.Typeface = TrySetFont(e.NewElement.FontName);
    }
}

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);

    switch (e.PropertyName)
    {
        case "Checked":
            Control.Text = Element.Text;
            Control.Checked = Element.Checked;
            break;
        case "TextColor":
            UpdateTextColor();
            break;
        case "FontName":
            if (!string.IsNullOrEmpty(Element.FontName))
            {
                Control.Typeface = TrySetFont(Element.FontName);
            }
            break;
        case "FontSize":
            if (Element.FontSize > 0)
            {
                Control.TextSize = (float)Element.FontSize;
            }
            break;
        case "CheckedText":
        case "UncheckedText":
            Control.Text = Element.Text;
            break;
       ** case "IsCheckBoxVisible":
            if(Element.IsCheckBoxVisible==true)
            {
                Control.Visibility = Android.Views.ViewStates.Visible;
            }
            else 
            {
                Control.Visibility = Android.Views.ViewStates.Invisible;
            }
            break;**
        default:
            System.Diagnostics.Debug.WriteLine("Property change for {0} has not been implemented.", e.PropertyName);
            break;
    }
}

1 个答案:

答案 0 :(得分:0)

所以这实际上应该非常简单。现在你有IsCheckBoxVisibleProperty,你可以一起摆脱它。 Xamarin.Forms.View已经有IsVisible属性,每个特定于平台的渲染器(VisualElementRenderer)都知道如何处理可见性。

因此,您可以毫无问题地执行此操作。

var checkbox = new Checkbox();
checkbox .SetBinding (Checkbox.IsVisibleProperty, "IsCheckboxVisible");

或者在您的XAML中

<controls:Checkbox IsVisible="{Binding IsCheckboxVisible}" />

当然这假设您有一个类似于。

的ViewModel
public class MyViewModel : BaseViewModel 
{
        private bool _isCheckboxVisible;
        public bool IsCheckboxVisible
        {
            get { return _isCheckboxVisible; }
            set { SetField(ref _isCheckboxVisible, value); }
        }
}