listview - listview 中动态创建的条目的边框颜色在 xamarin 中未按预期工作
问题描述
`我使用了自定义渲染器类,并且在条目的焦点上,边框颜色正在改变。
默认情况下不会启用条目,一旦用户选择一个图标,然后条目将被启用,然后在焦点上,颜色将变为其他内容。
我有一个图像按钮(要添加),我正在使用一个列表视图,里面有一个条目和一个图像按钮(要删除)。单击按钮时,条目和 imageButton(to delete) 正在动态创建。
一旦我选择了imageButton(删除),它就会删除那个特定的条目,然后我通过点击imageButton(添加)再次添加。
在那之后,当我试图把注意力集中在那个条目上时,边框颜色并没有像预期的那样改变。
当存在包含插入和删除操作的列表时,自定义渲染器不起作用。`
.xaml
<StackLayout x:Name="vehicleListLayout" Margin="40,0" VerticalOptions="Fill" >
<ScrollView>
<ListView x:Name="MyList" SeparatorVisibility="None" HasUnevenRows="True" ItemsSource="{Binding CollectionsList}"
Footer="" VerticalOptions="Fill" SelectionMode="None" HeightRequest="300" AutomationId="AutomationId_ProfileVehicleList"
IsEnabled="False">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Margin="0" RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<local:BorderedEntryRenderer
x:Name="VehicleEntry"
Text="{Binding VehicleNumber1}" WidthRequest="180"
Margin="5" VerticalOptions="Start" AutomationId="AutomationId_ProfileVehicle"/>
<ImageButton
x:Name="DeleteButton"
Margin="5" Command="{Binding Path=BindingContext.DeleteCommand, Source={x:Reference MyList}}"
CommandParameter="{Binding .}" Grid.Column="1" Source="baseline_remove_black_24"
HorizontalOptions="Start" HeightRequest="20" WidthRequest="25" BackgroundColor="Transparent"
AutomationId="AutomationId_ProfileDeleteVehicle"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
</StackLayout>
视图模型
private void AddItems(object obj)
{
Vehicles vehicles = new Vehicles();
CollectionsList.Insert(0, vehicles);
}
private void OnDeleteTapped(object obj)
{
var content = obj as Vehicles;
CollectionsList.Remove(content);
}
BorderedEntryRenderer 类(通用)
namespace DriverTracker
{
public class BorderedEntryRenderer : Entry
{
public static BorderedEntryRenderer Instance { get; } = new BorderedEntryRenderer();
public static readonly BindableProperty DefaultBorderColorProperty =
BindableProperty.Create(
nameof(DefaultBorderColor),
typeof(Color),
typeof(BorderedEntryRenderer),
Color.LightGray);
public Color DefaultBorderColor
{
get { return (Color)GetValue(DefaultBorderColorProperty); }
set { SetValue(DefaultBorderColorProperty, value); }
}
public static readonly BindableProperty SelectedBorderColorProperty =
BindableProperty.Create(
nameof(SelectedBorderColor),
typeof(Color),
typeof(BorderedEntryRenderer),
Color.LightSkyBlue);
public Color SelectedBorderColor
{
get { return (Color)GetValue(SelectedBorderColorProperty); }
set { SetValue(SelectedBorderColorProperty, value); }
}
安卓
namespace DriverTracker.Droid
{
public class AndroidBorderedEntryRenderer: EntryRenderer
{
public AndroidBorderedEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var view = (BorderedEntryRenderer)Element;
if (e.OldElement == null)
{
var gradientDrawable = new GradientDrawable();
gradientDrawable.SetCornerRadius((float)view.CornerRadius);
gradientDrawable.SetShape(ShapeType.Rectangle);
gradientDrawable.SetStroke(view.BorderWidth, view.DefaultBorderColor.ToAndroid());
e.NewElement.Unfocused += (sender, evt) =>
{
gradientDrawable.SetStroke(view.BorderWidth, view.DefaultBorderColor.ToAndroid());
};
e.NewElement.Focused += (sender, evt) =>
{
gradientDrawable.SetStroke(view.BorderWidth, view.SelectedBorderColor.ToAndroid());
};
Control.SetBackground(gradientDrawable);
}
}
}
iOS
namespace DriverTracker.iOS
{
public class iOSBorderedEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
var view = (BorderedEntryRenderer)Element;
Control.Layer.CornerRadius = (float)((BorderedEntryRenderer)Element).CornerRadius;
Control.Layer.BorderWidth = view.BorderWidth;
Control.Layer.BorderColor = view.DefaultBorderColor.ToCGColor();
e.NewElement.Unfocused += (sender, evt) =>
{
Control.Layer.BorderColor = view.DefaultBorderColor.ToCGColor();
};
e.NewElement.Focused += (sender, evt) =>
{
Control.Layer.BorderColor = view.SelectedBorderColor.ToCGColor();
};
}
}
}
解决方案
我简化了您的代码并对其进行了测试,它运行良好。您是否忘记向ExportRenderer
自定义渲染器类添加一个属性以指定它将用于渲染 Xamarin.Forms 控件?
[assembly: ExportRenderer(typeof(BorderedEntryRenderer), typeof(AndroidBorderedEntryRenderer))]
namespace DriverTracker.Droid
和
[assembly: ExportRenderer(typeof(BorderedEntryRenderer), typeof(iOSBorderedEntryRenderer ))]
namespace DriverTracker.iOS
更新:
添加CachingStrategy="RecycleElement"
到您的列表视图。
<ListView CachingStrategy="RecycleElement" x:Name="MyList" SeparatorVisibility="None" HasUnevenRows="True" ItemsSource="{Binding CollectionsList}"
Footer="" VerticalOptions="Fill" SelectionMode="None" HeightRequest="300" AutomationId="AutomationId_ProfileVehicleList"
IsEnabled="False">
...
</ListView >
推荐阅读
- javascript - Stripe Payment 集成 PHP JSON 在通过工作流传递电子邮件时遇到问题
- ansible - 在 Ansible 中的特定主机上基于 jinja2 模板生成配置
- ios - Xcode:架构 arm64 的未定义符号:“_OBJC_CLASS_$_ATTrackingManager”
- javascript - 添加身份验证后在其他选项卡屏幕上显示主页标题。(遵循反应导航文档)
- python - 如何通过 sqlalchemy 在多个(生成的)python 进程中使用 sqlite
- python - 如何在 Django 管理视图中显示链接对象?
- swift - 如何验证 Firestore 中的文档路径?
- python-3.x - 如何从python中的excel电子表格中将数据提取到字典列表中?
- php - 如何防止 cURL 在 WP 函数中被触发两次?
- solidity - 使用 truffle 在构造函数中使用参数测试智能合约