如何根据“选定的布尔”参数更改模板控件的属性(TextColor)?

时间:2018-10-31 08:26:30

标签: xamarin xamarin.forms

我有一个创建的按钮模板。它基于框架,并显示为方形按钮,单击该按钮可调用命令,还可以在后端使用一种方法在短时间内更改颜色。

按钮具有绑定参数(Enabled),可以为true或false。

我希望Label文本的颜色为true时为Color.Red,为false时为Color.Green。

<?xml version="1.0" encoding="UTF-8"?>
<t:ButtonBase xmlns="http://xamarin.com/schemas/2014/forms" 
                      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
                      xmlns:t="clr-namespace:Japanese.Templates" 
                      xmlns:local="clr-namespace:Japanese;assembly=Japanese" 
                      x:Class="Japanese.Templates.SquareButton" x:Name="this" >
    <t:ButtonBase.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding TapCommand, Source={x:Reference this}}" 
                              CommandParameter="{Binding TapCommandParam, Source={x:Reference this}}" 
                              NumberOfTapsRequired="1" />
        <TapGestureRecognizer Tapped="Tapped" />
    </t:ButtonBase.GestureRecognizers>
    <Label Text="{Binding Text, Source={x:Reference this}}" x:Name="ButtonLabel" 
           TextColor="{Binding LabelTextColor, Source={x:Reference this}}" />
</t:ButtonBase>

和后端c#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Japanese.Templates
{
    public partial class SquareButton : Frame
    {

    public static readonly BindableProperty EnabledProperty = BindableProperty.Create(nameof(Enabled), typeof(bool), typeof(ButtonBase), true);           
    public static readonly BindableProperty LabelTextColorProperty = BindableProperty.Create(nameof(LabelTextColor), typeof(Color), typeof(ButtonBase), default(Color));
    public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(ButtonBase), default(string));

    public bool Enabled { get { return (bool)GetValue(EnabledProperty); } set { SetValue(EnabledProperty, value); } }
    public Color LabelTextColor { get { return (Color)GetValue(LabelTextColorProperty); } set { SetValue(LabelTextColorProperty, value); } }
    public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } }

        public SquareButton()
        {
            InitializeComponent();
            BackgroundColor = (Color)Application.Current.Resources["SquareButtonBackgroundColor"];
        }

        protected async void Tapped(Object sender, EventArgs e)
        {
            BackgroundColor = (Color)Application.Current.Resources["CSquareButtonBackgroundColor"];
            await Task.Delay(500);
            BackgroundColor = (Color)Application.Current.Resources["SquareButtonBackgroundColor"];
        }
    }
}

模板使用

 <template:SquareButton Grid.Column="1" 
     Enabled="{Binding Btns[0].IsSelected}" 
     Text="{Binding Btns[0].Name}" 
     LabelTextColor="{Binding Btns[0].TextColor}" 
     TapCommand="{Binding BtnsBtnCmd }" 
     TapCommandParam="{Binding Btns[0].Name}" />

任何人都可以就如何使Enabled参数的值更改Red和Green之间的Label颜色提供任何建议。如果可能的话,我想在C#后端代码中执行此操作。

不确定这是否有帮助,但我正在查看此事件:

公共事件System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

我能以某种方式在后端C#中检测到这一点并根据更改时检查“启用”状态来设置颜色吗?

1 个答案:

答案 0 :(得分:1)

我认为您不需要在自定义控件中设置所有这些绑定(我想这是一个自定义控件?)。它只会造成比所需的更多的代码复杂性。您也不需要将两个TapGestureRecognizer置于同一个控件中(下面进一步说明)。另外,强烈建议不要调用元素this,因为this是对当前实例的有效C#引用,将导致问题。这样您就可以摆脱所有这些问题:

<?xml version="1.0" encoding="UTF-8"?>
<t:ButtonBase 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:t="clr-namespace:Japanese.Templates" 
    xmlns:local="clr-namespace:Japanese;assembly=Japanese" 
    x:Class="Japanese.Templates.SquareButton" >
    <t:ButtonBase.GestureRecognizers>
        <TapGestureRecognizer 
            Tapped="Tapped" />
    </t:ButtonBase.GestureRecognizers>
    <Label 
        x:Name="ButtonLabel"
        Text="SomeDefaultText"  
        TextColor="Color.Default" />
</t:ButtonBase>

接下来,在您的SquareButton类中,您和PropertyChangedEventHandler处在正确的轨道上。但是,它通常与标准属性一起使用,并且在继承INotifyPropertyChanged时必须使用。

您真正要寻找的是propertyChanged创建方法中的BindableProperty自变量。这将分配一个事件,以便在属性更改时将触发此事件。例如:

// Create your bindable property
public static readonly BindableProperty EnabledProperty = 
    BindableProperty.Create(
        propertyName: nameof(Enabled), 
        returnType: typeof(bool), 
        declaringType: typeof(ButtonBase), 
        defaultValue: true,
        propertyChanged: HandleEnabledPropertyChanged);  // <= The property changed handler!!

// The property
public bool Enabled 
{ 
    get => (bool)GetValue(EnabledProperty); 
    set => SetValue(EnabledProperty, value); 
}

// Create your property-changed handler
private static void HandleEnabledPropertyChanged(
    BindableObject bindable, object oldValue, object newValue)
{
    var control = (SquareButton)bindable;
    if (control != null)
    {
        control.ButtonLabel.TextColor = 
            ((bool)newValue) ? 
            Color.Red : 
            Color.Green; 
    }
}

如果您想为TapGestureRecognizer的{​​{1}}事件添加其他功能,则需要为此实现另一个处理程序。例如:

Tapped