Xamarin上的自定义复选框默认文本绑定

时间:2017-12-19 12:18:38

标签: c# xamarin data-binding binding xamarin.forms

我有一个自定义Checkbox,如下所示;

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

    /// <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,BindingMode.TwoWay, propertyChanged: OnDefaultTextChanged);

    /// <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 PropertyChangedEventHandler PropertyChanged;


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

    /// <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);
            NotifyPropertyChanged("DefaultTextProperty");
            NotifyPropertyChanged("DefaultText");


        }
    }

    /// <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 void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我有默认文本可绑定属性,我想通过Binding设置来自即将到来的Web服务的值。

我在Xaml上尝试的代码如下;

<uikit:CheckBox x:Name="CheckBox" WidthRequest="250" HeightRequest="100" FontSize="13" DefaultText="{Binding FirstText,Mode=TwoWay}"  CheckedChanged="CheckBox_Clicked" TextColor="#263238" />

我无法这样做...我尝试在Xaml和Codebehind中设置绑定上下文。

我做错了什么?

你能帮我吗?

我还添加了PropertyChanged事件处理程序,我的更新代码如上所述。它仍然没有更新。

BR,

1 个答案:

答案 0 :(得分:1)

在最后添加

public void RaiseCheckedChanged (bool val)
{
    if (CheckedChanged != null)
        CheckedChanged (this, new EventArgs<bool> (val));
}

并在同一个文件中添加此类

 public class EventArgs<T> : EventArgs
{
    /// <summary>
    /// Initializes a new instance of the <see cref="EventArgs"/> class.
    /// </summary>
    /// <param name="value">Value of the argument</param>
    public EventArgs(T value)
    {
        this.Value = value;
    }

    /// <summary>
    /// Gets the value of the event argument
    /// </summary>
    public T Value { get; private set; }
}

public static class BindableObjectExtensions
{
    /// <summary>
    /// Gets the value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="bindableObject">The bindable object.</param>
    /// <param name="property">The property.</param>
    /// <returns>T.</returns>
    public static T GetValue<T>(this BindableObject bindableObject, BindableProperty property)
    {
        return (T)bindableObject.GetValue(property);
    }
}

public static class EventExtensions
{
    /// <summary>
    /// Raise the specified event.
    /// </summary>
    /// <param name="handler">Event handler.</param>
    /// <param name="sender">Sender object.</param>
    /// <param name="value">Argument value.</param>
    /// <typeparam name="T">The value type.</typeparam>
    public static void Invoke<T>(this EventHandler<EventArgs<T>> handler, object sender, T value)
    {
        var handle = handler;
        if (handle != null)
        {
            handle(sender, new EventArgs<T>(value));
        }
    }

    /// <summary>
    /// Tries the invoke.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="handler">The handler.</param>
    /// <param name="sender">The sender.</param>
    /// <param name="args">The arguments.</param>
    /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
    public static bool TryInvoke<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs
    {
        var handle = handler;
        if (handle == null) return false;

        handle(sender, args);
        return true;
    }
}