首页 > 解决方案 > 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();
            };

        }
    }
}

 

标签: listviewxamarin

解决方案


我简化了您的代码并对其进行了测试,它运行良好。您是否忘记向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  >

推荐阅读