在运行时更改Xamarin.Forms的颜色

3
我正在使用Xamarin.Forms制作一个应用程序,并设置了一种颜色方案,希望能够在设置中更改为暗色或浅色风格。目前,所有功能都可以正常工作,但每次选择不同的颜色方案后都需要重新启动应用程序。
以下是我尝试在运行时更改颜色方案的位置:
   private void DarkThemeClick(object sender, EventArgs e)
    {
        database.DropTable(new StyleModel());
        database.CreateTable(new StyleModel());
        database.SaveItem(new StyleModel() { ThemeNum = 1 });
        App.ActiveStyle = new DarkStyle();
    }

    private void LightThemeClick(object sender, EventArgs e)
    {
        database.DropTable(new StyleModel());
        database.CreateTable(new StyleModel());
        database.SaveItem(new StyleModel() { ThemeNum = 0 });
        App.ActiveStyle = new LightStyle();
    }

这是一个我正在使用的项目示例,我想更改其颜色。
    using System;
using TestXamForms.Style;
using Xamarin.Forms;

namespace TestXamForms.Helpers
{
class EntryValueCell : StackLayout
{

    public EntryValueCell(string key,int FieldIdx, string value = "",  bool isNumber = false)
    {
        Entry entry;
        Label label = new Label()
        {
            TextColor = App.ActiveStyle.LabelTextColor,
            Text = key,
            HorizontalOptions = LayoutOptions.End
        };
        if (isNumber)
        {
            entry = new Entry()
            {
                ClassId = FieldIdx.ToString(),
                TextColor = App.ActiveStyle.LabelTextColor,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Keyboard = Keyboard.Numeric,
                Text = value, 


            };
        }
        else
        {
            entry = new Entry()
            {
                ClassId = FieldIdx.ToString(),
                TextColor = App.ActiveStyle.LabelTextColor,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Keyboard = Keyboard.Text,
                Text = value
            };
        }

        BackgroundColor = App.ActiveStyle.StackLayoutBackground;
        Orientation = StackOrientation.Horizontal;
        VerticalOptions = LayoutOptions.FillAndExpand;
        Children.Add(label);
        Children.Add(entry);
    }
}
}

这是一个颜色方案的示例。
    using Xamarin.Forms;

   namespace TestXamForms.Style
 {
     public  class LightStyle : StyleBase
    {
       public LightStyle()
        {
        LabelTextColor = Color.Black;
        ButtonColor = Color.FromHex("337ab7");
        StackLayoutBackground = Color.FromHex("eff0f1");
        InputBackgroundColor = Color.White;
        PlaceHolderColor = Color.Gray;
        TableColor = Color.FromHex("e6e6e6");
        StacklayoutBorderColor = Color.Black;
       }
      }
     }

这里是styleBase,上面的文件正在继承它

using TestXamForms.Models;
using Xamarin.Forms;

namespace TestXamForms.Style
{
public class StyleBase : ModelBase
{
    public enum ThemeNum : int
    {
        Light = 0, Dark = 1
    }
    public Color LabelTextColor { get; set; }
    public Color ButtonColor { get; set; }
    public Color StackLayoutBackground { get; set; }
    public Color InputBackgroundColor { get; set; }
    public Color PlaceHolderColor { get; set; }

    public Color StacklayoutBorderColor { get; set; }

    public Color TableColor { get; set; }

    public int ThemeNums { get; set; }

}
}

这是 App.cs 文件中负责在应用程序启动时加载颜色方案的部分代码。
    static StyleBase activeStyle { get; set; }


    public static StyleBase ActiveStyle
    {
        get
        {
            if (activeStyle == null)
            {
                StyleModel styleBase = database.GetItems(new     StyleModel()).First();
                if (styleBase == null)
                {
                    database.SaveItem(new StyleModel() { ThemeNum = 0 }); //sets the default color scheme to light style 
                    styleBase = database.GetItems(new StyleModel()).First();
                }
                int themeNum = styleBase.ThemeNum;
                switch (themeNum)
                {
                    case (int)StyleBase.ThemeNum.Dark:
                        activeStyle = new DarkStyle();
                        break;
                    case (int)StyleBase.ThemeNum.Light:
                        activeStyle = new LightStyle();
                        break;
                }
            }
            return activeStyle;
        }
        set { } }

你想在单击事件发生时更改主题吗? - nishantvodoo
是的,我希望在那个时刻进行更改,然后保存该选择,以便下次打开应用程序时使用..第二部分现在正在工作。 - hartk1213
一旦视图已经被渲染,除非你绑定到一个属性,否则它不会更新。换句话说,你需要从头开始重新渲染所有内容。 - nishantvodoo
好的,那样就有意义了,谢谢。 - hartk1213
2个回答

3
请看这篇博客文章,特别是关于DynamicResourcesStyles的部分。
<Application
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Your.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="backgroundColor">#33302E</Color>
            <Color x:Key="textColor">White</Color>
        </ResourceDictionary>
    </Application.Resources>
</Application>

现在设置你的资源。
<Label Text="{Binding Name}" FontSize="Medium" FontAttributes = "Bold" TextColor = "{DynamicResource textColor}" LineBreakMode="NoWrap"/>
<Label Text="{Binding Text}" FontSize="Small" LineBreakMode="WordWrap" TextColor = "{DynamicResource textColor}"/>

现在在代码中,你可以实时更改你的资源。
App.Current.Resources ["backgroundColor"] = Color.White;
App.Current.Resources ["textColor"] = Color.Black;

如果您在使用2.3版本,您也可以尝试使用内置的主题。请点击此处查看相关文档:内置主题

谢谢。现在我可以在运行时更改表单的颜色了。 - fulvio
请参考以下链接了解合并字典的方法:https://dev59.com/qnRB5IYBdhLWcg3wc280#62850549 - DevDave

1
你面临的问题是所有内容都已经被渲染,而你没有绑定到任何属性,这些属性可以重新渲染代码对UI所做的更改。您可以采用MVVM方法创建属性并绑定它们,并在UI线程中更改时进行通知。
如果您只对暗色和亮色主题感兴趣,则可以使用内置的Light ThemeDark Theme。您还可以创建Custom Themes
引用:
通过包括Xamarin.Forms.Theme.Base Nuget包以及定义特定主题(例如Xamarin.Forms.Theme.Light)的其他包或为应用程序定义本地主题,可以将主题添加到Xamarin.Forms应用程序中。
除了自动为常见控件设置样式外,亮色和暗色主题目前还支持可以通过在这些控件上设置StyleClass来应用的以下类:
  • BoxView - 水平线、圆形、圆角

  • Image - 圆形、圆角、缩略图

  • Button - 默认、主要、成功、信息、警告、危险、链接、小号、大号

  • Label - 标题、副标题、正文、链接、反色

要向应用程序添加主题,请执行以下操作:

  1. Add the Nuget packages to your project.

  2. Add theme to Resource Dictionary in App.xaml

  3. Use the Style class to apply predefined style classes in the theme.

    <Button Text="Button Class Default" StyleClass="Default" />
    <Button Text="Button Class Primary" StyleClass="Primary" />
    <Button Text="Button Class Success" StyleClass="Success" />
    

阅读更多关于主题的内容这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接