我正在开发一个Xamarin应用程序,我正在Android设备上测试。我有一个XAML视图,我正在绑定视图模型中的枚举属性到多个控件-一个用于文本值,另一个用IValueConverter绑定到背景色。相关XAML代码:
<ContentView
BackgroundColor="{Binding MyField, Converter={StaticResource MyFieldEnumValueToColorConverter}}"
>
<ContentView.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding MyFieldClickCommand}" />
</ContentView.GestureRecognizers>
<Label
Text="{Binding MyField}"
/>
</ContentView>
IValueConverter实现:
public class MyFieldEnumValueToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is MyFieldEnum)
{
switch ((MyFieldEnum)value)
{
case MyFieldEnum.Value1:
return Color.Orange;
case MyFieldEnum.Value2:
return Color.Green;
case MyFieldEnum.Value3:
return Color.Red;
}
}
return Color.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
视图模型中的属性(是的,它确实实现了INotifyPropertyChanged):
public event PropertyChangedEventHandler PropertyChanged;
private MyFieldEnum _myField;
public MyFieldEnum MyField
{
get => _myField;
set
{
_myField= value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyField)));
}
}
当我加载这个页面时,控件为每个不同的枚举值正确加载:文本和背景颜色都反映实际值。
在单击处理程序中,我只是像这样设置属性值:
MyField = MyFieldEnum.Value2;
文本更改,但背景颜色不变。为什么?
我还尝试引入一个新字段(类型为Color),直接在getter中实现IValueConverter逻辑,并将其绑定到ContentView的BackgroundColor属性。同样的问题。该页面有许多其他数据绑定项,除此之外,所有项都工作正常。
更新:看起来问题出在ContentView上。我把完全相同的BackgroundColor绑定到标签本身,在那里它按预期工作,但对于ContentView来说它不是。
1条答案
按热度按时间yiytaume1#
所以我找到了根本原因。
ContentView还有一个定义在StaticResource中的样式,它向控件添加了一些样式规则(包括背景颜色)。为了简洁起见,我方便地从问题中省略了这个样式。我认为这可能是一个问题,所以我从样式中删除了背景颜色,但问题仍然存在。我摆弄了XAML属性顺序,因为我记得它以前给了我很大的困难,但也没有运气。
我仔细查看了定义的样式,发现样式包含一个Xamarin.Forms RoutingEffect,用于可配置半径的圆角。在检查代码的Android特定实现时,我意识到它实现了圆角半径,它将背景颜色设置为透明,并将容器层的背景颜色设置为原始背景颜色和圆角半径。据我所知,这段代码在元素渲染(OnAttached)时运行一次。最初绑定的背景色是正确的,因为它之前应用过,但它被覆盖了,我相信当效果将视图的背景色设置为透明时,绑定被覆盖/删除了。
我从元素中删除了效果,确认了这是根本原因,并且它开始按预期工作。当然,我为这个元素去掉了圆角,这使得UI不一致,但这是改天的问题。谢谢大家的建议!