在其中一个最新版本中,Xamarin.Forms添加了将工具栏放在底部(2009q4
)并在ToolBarPlacement
上设置属性BarBackgroundColor
的可能性。工具栏可以更改。
不幸的是,当工具栏被拆分时(这是Windows 10 Mobile上的默认设置或NavigationPage
是底部的),两个栏都具有相同的背景颜色。
在我的应用程序中,我希望实现顶部栏(带标题和汉堡菜单)具有系统的强调颜色,底栏(带有命令和弹出按钮)为灰色,因为此组合也被使用by many system apps (例如,Windows 10 Mobile上的邮件或日历)。
但是,如果不触及Xamarin.Forms中的核心实现,我无法弄清楚如何做到这一点。我已尝试过自定义ToolbarPlacement
和自定义NavigationPageRenderer
,但许多相关字段都是私有,密封或内部或正在访问内部接口。
两个条形图的背景颜色似乎绑定到相同的属性,因为在Visual Studio的Live XAML树视图中更改一个条形图的背景也会更改另一个条形图的颜色。
任何有关如何实现所需外观的帮助都将受到赞赏。
答案 0 :(得分:1)
最后,我取得了理想的结果。
其中一个问题是我的RootPage是MasterDetailPage
,因此我必须创建一个MasterDetailPageRenderer
。此外,我假设Xamarin将使用实际的UWP页面的TopAppBar
和BottomAppBar
属性。事实并非如此。
使用以下MasterDetailPageRenderer
顶部栏(带有汉堡菜单按钮和标题)显示为绿色,而底栏保持默认灰色(基本上渲染器只删除代表StackPanel的Background
绑定顶部栏并将其设置为绿色)。一个问题是,FindName和FindByName方法不起作用(总是返回null),所以我不得不使用VisualTreeHelper滚动我自己的实现。
[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(CustomMasterDetailPageRender))]
public class CustomMasterDetailPageRender : MasterDetailPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<MasterDetailPage> e)
{
base.OnElementChanged(e);
if (Element != null)
{
Element.Appearing += Element_Appearing;
}
}
private void Element_Appearing(object sender, EventArgs e)
{
(sender as MasterDetailPage).Appearing -= Element_Appearing;
if (Control != null)
{
var topBarArea = FindElementByName(Control, "TopCommandBarArea");
if (topBarArea != null)
{
var topContent = FindElementByType<StackPanel>(topBarArea);
if (topContent != null)
{
topContent.Background = new SolidColorBrush(Colors.Green);
}
}
}
}
static DependencyObject FindElementByName(DependencyObject parent, string name)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var sub = VisualTreeHelper.GetChild(parent, i);
if (sub is FrameworkElement)
{
if (((FrameworkElement)sub).Name == name)
{
return sub;
}
}
var r = FindElementByName(sub, name);
if (r != null)
return r;
}
return null;
}
static T FindElementByType<T>(DependencyObject parent)
where T: DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var sub = VisualTreeHelper.GetChild(parent, i);
if (sub is T)
{
return (T)sub;
}
var r = FindElementByType<T>(sub);
if (r != null)
return r;
}
return null;
}
}