如何在iOS ViewCellRenderer中更改窗体ViewList的MenuItem颜色?

问题描述 投票:2回答:2

有没有办法改变Xamarin.Forms Xaml文件中添加的ContextAction菜单的颜色。 IsDestructive="True"将菜单颜色设置为红色。但我需要另一个菜单看起来像绿色或其他颜色。

这是我的Forms Xaml代码..

<ListView x:Name="planList" ItemsSource="{x:Static local:SampleData.PLAN_DATA}" RowHeight="150" HorizontalOptions="FillAndExpand">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.ContextActions>
                    <MenuItem Clicked="OnEditClick" Text="Edit" CommandParameter="{Binding .}"/> <!-- THIS HAS TO BE GREEN COLOR -->
                    <MenuItem Clicked="OnDeleteClick" Text="Delete" IsDestructive="True" />
                </ViewCell.ContextActions>
                <ViewCell.View>
                    <StackLayout Orientation="Vertical"  HorizontalOptions="Start" VerticalOptions="FillAndExpand">
                        <!--Non Editable State-->
                        <StackLayout Orientation="Horizontal" Spacing="28" IsVisible="{Binding isNotSaveState}">
                            <Frame  WidthRequest="130" HeightRequest="50" BackgroundColor="#151617" HorizontalOptions="Start">
                                <Label Text="{Binding from}" TextColor="#ff9600" FontSize="Medium" FontFamily="Helvetica"/>
                            </Frame>
                        </StackLayout>
                        <!--Editable State-->
                        <StackLayout Orientation="Horizontal" Spacing="0"  IsVisible="{Binding isSaveState}">
                            <StackLayout Orientation="Horizontal" Spacing="5">
                                <Label Text="From" TextColor="#838288"  FontSize="Medium" FontFamily="Helvetica"/>
                                <Entry Text="" BackgroundColor="Red"/>
                            </StackLayout>
                            <Button Text="Save" BackgroundColor="Green" CommandParameter="{Binding .}" Clicked="onSaveClick" />
                        </StackLayout>
                    </StackLayout>
                </ViewCell.View>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这是我的渲染器..

[assembly: ExportRenderer(typeof(MyApp.Views.Cells.CustomViewCell), typeof(MyApp.iOS.Views.Cells.CustomViewCellRenderer))]
namespace MyApp.iOS.Views.Cells
{

    public class CustomViewCellRenderer : ViewCellRenderer
    {
        public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
        {
            UITableViewCell cell = base.GetCell(item, reusableCell, tv);

            // I have no Idea how to access the Swipe Menus from Renderer

            //cell.EditingAccessory
            //cell.EditingAccessoryView

            return cell;
        }        
    }
}
ios xaml xamarin.ios xamarin xamarin.forms
2个回答
4
投票

Xamarin通过子类化ContextActionsCell的本机单元UITableViewCell实现上下文菜单。

但是,截至今天的Xamarin.Forms.Platform.iOS(1.4.0.6340-pre2)程序集,设置手势和按钮的ContextActionsCell仍然是internal类,对于更改任何内容都无法访问或继承。


可是等等!

不过,你可以使用Reflection改变internal以上的东西。

例:

// Get UIImage with a green color fill
CGRect rect = new CGRect (0, 0, 1, 1);
CGSize size = rect.Size;
UIGraphics.BeginImageContext (size);
CGContext currentContext = UIGraphics.GetCurrentContext ();
currentContext.SetFillColor (0, 1, 0, 1);
currentContext.FillRect (rect);
var backgroundImage = UIGraphics.GetImageFromCurrentImageContext ();
currentContext.Dispose ();

// This is the assembly full name which may vary by the Xamarin.Forms version installed.
// NullReferenceException is raised if the full name is not correct.
var t = Type.GetType("Xamarin.Forms.Platform.iOS.ContextActionsCell, Xamarin.Forms.Platform.iOS, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null");

// Now change the static field value!
var field = t.GetField ("destructiveBackground", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
field.SetValue (null, backgroundImage);

注1:这将改变所有上下文菜单的破坏性背景颜色。

注意2:如果您还想更改正常颜色,则字段名称为normalBackground

注3:Xamarin可以制作这些类internal,其目的是API和行为将来可能会发生变化。以上示例可能会在即将发布


2
投票

对于Xamarin.Forms.2.3.3.193和Xamarin.Forms.Platform.iOS(2.x)版本号版本= 2.0.0.0并且字段名称Case已更改为NormalBackground&DestructiveBackground

using System;

using CoreGraphics;
using Foundation;
using UIKit;

using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using System.Reflection;

[assembly: ExportRenderer(typeof(ViewCell), typeof(App.Renderers.CustomViewCellRenderer))]
namespace App.Renderers
{    
    public class CustomViewCellRenderer : ViewCellRenderer
    {
        public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
        {
            UITableViewCell cell = base.GetCell(item, reusableCell, tv);

            try
            {
                // This is the assembly full name which may vary by the Xamarin.Forms version installed.
                // NullReferenceException is raised if the full name is not correct.
                var globalContextViewCell = Type.GetType("Xamarin.Forms.Platform.iOS.ContextActionsCell, Xamarin.Forms.Platform.iOS, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null");

                // Now change the static field value! "NormalBackground" OR "DestructiveBackground"
                if(globalContextViewCell != null)
                {
                    var normalButton = globalContextViewCell.GetField("NormalBackground", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

                    if (normalButton != null)
                    {
                        normalButton.SetValue(null, getImageBasedOnColor("ff9500"));
                    }      

                    var destructiveButton = globalContextViewCell.GetField("DestructiveBackground", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

                    if (destructiveButton != null)
                    {
                        destructiveButton.SetValue(null, getImageBasedOnColor("B3B3B3"));
                    }                        
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Error in setting background color of Menu Item : " + e.ToString());
            }

            return cell;
        }

        private UIImage getImageBasedOnColor(string colorCode)
        {
            // Get UIImage with a green color fill
            CGRect rect = new CGRect(0, 0, 1, 1);
            CGSize size = rect.Size;
            UIGraphics.BeginImageContext(size);
            CGContext currentContext = UIGraphics.GetCurrentContext();
            currentContext.SetFillColor(Color.FromHex(colorCode).ToCGColor());
            currentContext.FillRect(rect);
            var backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
            currentContext.Dispose();

            return backgroundImage;
        }


    }


}
© www.soinside.com 2019 - 2024. All rights reserved.