【发布时间】:2021-12-08 08:07:13
【问题描述】:
我正在创建一个 Xamarin.Forms MVVM 应用程序(仅使用 Android),只要它们的文本属性具有特定值,就需要将某些按钮标为红色。 (目的:提醒用户按下按钮并选择一个值,这将改变按钮文本属性,从而去除红色轮廓)
为此,我创建了以下文档:
自定义按钮 CButton 扩展默认 Button:
public class CButton : Button
{
// this Hides the Default .Text-Property
public string Text
{
get => base.Text;
set
{
base.Text = value;
TextChangedEvent(this, new EventArgs());
}
}
// The Raised Event
protected virtual void TextChangedEvent(object sender, EventArgs e)
{
EventHandler<EventArgs> handler = TextChanged;
handler(sender, e);
}
public event EventHandler<EventArgs> TextChanged;
}
自定义行为使用了引发的TextChangedEvent
public class ButtonValBehavior : Behavior<CButton>
{
protected override void OnAttachedTo(CButton bindable)
{
bindable.TextChanged += HandleTextChanged;
base.OnAttachedTo(bindable);
}
void HandleTextChanged(object sender, EventArgs e)
{
string forbidden = "hh:mm|dd.mm.yyyy";
if (forbidden.Contains((sender as CButton).Text.ToLower()))
{
//Do when Button Text = "hh:mm" || "dd.mm.yyyy"
(sender as CButton).BorderColor = Color.Gray;
}
else
{
//Do whenever Button.Text is any other value
(sender as CButton).BorderColor = Color.FromHex("#d10f32");
}
}
protected override void OnDetachingFrom(CButton bindable)
{
bindable.TextChanged -= HandleTextChanged;
base.OnDetachingFrom(bindable);
}
}
ViewModel 的相关部分如下所示:
public class VM_DIVI : VM_Base
{
public VM_DIVI(O_BasisProtokoll base)
{
Base = base;
}
private O_BasisProtokoll _base = null;
public O_BasisProtokoll Base
{
get => _base;
set
{
_base = value;
OnPropertyChanged();
}
}
Command _datePopCommand;
public Command DatePopCommand
{
get
{
return _datePopCommand ?? (_datePopCommand = new Command(param => ExecuteDatePopCommand(param)));
}
}
void ExecuteDatePopCommand(object param)
{
//launch popup
var p = new PP_DatePicker(param);
PopupNavigation.Instance.PushAsync(p);
}
}
.xmal 看起来如下(b 是命名空间的xmlns):
<b:CButton x:Name="BTN_ED_Datum"
Text="{Binding Base.ED_datum, Mode=TwoWay}"
Grid.Column="1"
Command="{Binding DatePopCommand}"
CommandParameter="{x:Reference BTN_ED_Datum}">
<b:CButton.Behaviors>
<b:ButtonValBehavior/>
</b:CButton.Behaviors>
</b:CButton>
只要输入是由用户交互引起的,此解决方案就可以正常工作。但是,在页面初始化期间分配值时,不会创建红色轮廓,实际上不会引发 TextChangedEvent。通过使用断点,我注意到在初始化期间,CButton 的 Text 属性从未设置过,尽管它实际上会在视图中。
尽管摆弄我的解决方案,但我无法在初始化时完成这项工作。我试图通过在构造函数中默认列出每个按钮来解决这个问题,但是这会将每个按钮都勾勒成红色,即使它们的文本值不需要它们也是如此。
我怎样才能实现我最初的目标?
非常感谢!
【问题讨论】:
-
在继承的类中定义同名的新属性通常不是一个好主意,尤其是当您尝试隐藏的属性与其他属性交互时。基类
Button上的 TextProperty 可绑定属性不知道您的新Text属性,这可能是您行为不一致的根源。我建议在您的子类中使用 PropertyChanged 事件并检查e.PropertyName == nameof(Text)。 -
正如 Andrew 所说,尝试将属性
Text修改为另一个名称,例如MyText,并在 xaml 中使用新属性。
标签: button events xamarin.forms data-binding behavior