如何更改 iOS ViewCellRenderer 中 Forms ViewList 的 MenuItem 颜色?
How to Change the MenuItem Colors of Forms ViewList in iOS ViewCellRenderer?
有什么方法可以更改 Xamarin.Forms Xaml 文件中添加的 ContextAction 菜单的颜色。 IsDestructive="True"
将菜单颜色设置为红色。但是我需要另一个看起来像绿色或其他颜色的菜单。
这是我的表格 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;
}
}
}
Xamarin 通过本机单元格 ContextActionsCell
子class UITableViewCell
.
实现上下文菜单
但是,截至今天 Xamarin.Forms.Platform.iOS (1.4.0.6340-pre2) 程序集,设置手势和按钮的 ContextActionsCell
仍然是 internal
class,无法访问或继承以更改任何内容。
等等!
不过,您可以使用 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 可能会制作这些 classes internal
,目的是 API 和行为可能在未来发生变化。以上示例可能会在即将发布的版本中中断。
对于Xamarin.Forms.2.3.3.193 & Xamarin.Forms.Platform.iOS (2.x)版本号Version=2.0.0.0 字段名称大小写更改为 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;
}
}
}
有什么方法可以更改 Xamarin.Forms Xaml 文件中添加的 ContextAction 菜单的颜色。 IsDestructive="True"
将菜单颜色设置为红色。但是我需要另一个看起来像绿色或其他颜色的菜单。
这是我的表格 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;
}
}
}
Xamarin 通过本机单元格 ContextActionsCell
子class UITableViewCell
.
但是,截至今天 Xamarin.Forms.Platform.iOS (1.4.0.6340-pre2) 程序集,设置手势和按钮的 ContextActionsCell
仍然是 internal
class,无法访问或继承以更改任何内容。
等等!
不过,您可以使用 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 可能会制作这些 classes internal
,目的是 API 和行为可能在未来发生变化。以上示例可能会在即将发布的版本中中断。
对于Xamarin.Forms.2.3.3.193 & Xamarin.Forms.Platform.iOS (2.x)版本号Version=2.0.0.0 字段名称大小写更改为 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;
}
}
}