C# 更新ResourceTheme不反映UWP应用程序中的文本框边框笔刷

C# 更新ResourceTheme不反映UWP应用程序中的文本框边框笔刷,c#,xaml,uwp,C#,Xaml,Uwp,我正在从代码隐藏中更新应用程序ThemeResource。它正在更改应用程序主题,但TextBoxBorderBrush属性未得到更新 我有一个自定义资源MyBorderBrush,用于我在App.xaml中定义的Dark和Light主题 Xaml: 编辑 我认为问题可能与代码隐藏或定义资源有关,因此我只共享了最少的代码以重现问题。但正如@ashq所指出的,问题在于文本框。事实上,我将BorderBrush属性绑定到转换器以获得正确的值,但是在更改主题时,边框颜色并没有改变 转换器: publ

我正在从代码隐藏中更新应用程序
ThemeResource
。它正在更改应用程序主题,但TextBox
BorderBrush
属性未得到更新

我有一个自定义资源
MyBorderBrush
,用于我在App.xaml中定义的
Dark
Light
主题

Xaml:

编辑

我认为问题可能与代码隐藏或定义资源有关,因此我只共享了最少的代码以重现问题。但正如@ashq所指出的,问题在于文本框。事实上,我将
BorderBrush
属性绑定到转换器以获得正确的值,但是在更改主题时,边框颜色并没有改变

转换器:

 public class BorderBrushColorConverter : IValueConverter
 {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var isError = value as bool? ?? false;
            return isError
                ? Application.Current.Resources["MyBorderBrushMandatory"] as SolidColorBrush
                : Application.Current.Resources["MyBorderBrush"] as SolidColorBrush;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
}
App.xaml

<ResourceDictionary x:Key="Light" >
             <Color x:Key="MyBorder">#6b6b6b</Color>
             <SolidColorBrush x:Key="MyBorderBrush" Color="{ThemeResource MyBorder}" />

              <Color x:Key="MyBorderMandatory">#ff0000</Color>
              <SolidColorBrush x:Key="MyBorderBrushMandatory" Color="{ThemeResource MyBorderMandatory}" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark" >
               <Color x:Key="MyBorder">#c85332</Color>
               <SolidColorBrush x:Key="MyBorderBrush" Color="{ThemeResource MyBorder}" />

               <Color x:Key="MyBorderMandatory">#FFD700</Color>
               <SolidColorBrush x:Key="MyBorderBrushMandatory" Color="{ThemeResource MyBorderMandatory}" />
</ResourceDictionary>

#6b
#ff0000
#c85332
#FFD700

您正在运行时更改动态主题。因此,将StaticResource更改为meresource。就这些


谢谢。

您正在运行时更改动态主题。因此,将StaticResource更改为meresource。就这些


谢谢。

您不应该将画笔绑定到
文本框的
边框画笔
,这意味着您已经为
边框画笔
设置了固定的画笔值。在xaml中使用
Binding
IValueConverter
时,它会将“MyBorderBrushEmmandatory”或“MyBorderBrush”资源中的
SolidColorBrush
值指定给
BorderBrush
,它是一个静态值,不会根据主题的更改而更改。简而言之,类似于将红色固定的
solidcolorbush
设置为
BorderBrush
,与动态主题资源无关

如果要在更改主题时更改
TextBox
BorderBrush
,只需将xaml
TextBox
绑定代码替换为主题资源引用:

<TextBox PlaceholderText="My PlaceholderText" Height="100" Width="500"
         HorizontalAlignment="Center" 
         BorderBrush="{ThemeResource MyBorderBrushMandatory}"
         VerticalAlignment="Center" ></TextBox>
MainPage.xaml.cs:

public sealed partial class MainPage : Page,INotifyPropertyChanged
{
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
        this.ActualThemeChanged += MainPage_ActualThemeChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void MainPage_ActualThemeChanged(FrameworkElement sender, object args)
    {
        IsError = !IsError;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.RequestedTheme = this.RequestedTheme == ElementTheme.Light ? ElementTheme.Dark : ElementTheme.Light;
    }

    private void OnPropertyChanged(string Name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(Name));
        }
    }

    private bool? isError=true;
    public bool? IsError
    {
        get
        {
            return isError;
        }
        set
        {
            isError = value;
            OnPropertyChanged("IsError");
        }
    }

}
---更新---

让我们谈谈你的样品。 首先,我们都知道,通过从App.xaml获取应用程序资源,可以设置
文本框的
边框笔刷。在Page2.xaml.cs中,使用以下代码

this.RequestedTheme = App.SelectedTheme;
这段代码只设置UIElement(及其子元素)用于确定资源的UI主题,也就是说,代码只设置页面的主题,而不设置应用程序。默认情况下,您的应用程序使用用户在Windows设置中设置的主题运行(设置>个性化设置>颜色>选择默认应用程序模式),您还可以将应用程序的属性设置为覆盖用户默认设置并指定使用的主题

作为部分:

主题只能在应用程序启动时设置,而不能在应用程序运行时设置。在应用程序运行时尝试设置RequestedTheme会引发异常(Microsoft.NET代码的NotSupportedException)。如果您允许用户选择属于应用程序UI的主题,则必须在应用程序数据中保存该设置,并在应用程序重新启动时应用该设置

因此,当您更改页面的
RequestedTheme
时,这不会影响应用程序的,它仍然是您在示例的App.xaml上设置的应用程序,因为代码

RequestedTheme="Light"
因此,当您使用code
Application.Current.Resources
获取应用程序资源时,它仍然会获取“Light”主题资源。这与您使用的是不同的。对于您的这个问题,主题资源不是您想要的,您应该在资源中设置一些不同颜色的笔刷,然后根据页面的资源设置使用获取不同颜色的笔刷资源

---更新2---

下面是一个简单的解决方案,只需在App.xaml中添加应用程序资源

<Application.Resources>
        <Color x:Key="MyBorder">#6b6b6b</Color>
        <SolidColorBrush x:Key="MyBorderBrush" Color="{StaticResource MyBorder}" />

        <Color x:Key="MyBorderMandatory">#ff0000</Color>
        <SolidColorBrush x:Key="MyBorderBrushMandatory" Color="{StaticResource MyBorderMandatory}" />

        <Color x:Key="MyBorderDark">#c85332</Color>
        <SolidColorBrush x:Key="MyBorderBrushDark" Color="{StaticResource MyBorderDark}" />

        <Color x:Key="MyBorderMandatoryDark">#FFD700</Color>
        <SolidColorBrush x:Key="MyBorderBrushMandatoryDark" Color="{StaticResource MyBorderMandatoryDark}" />
...
</Application.Resources>
在Page2.xaml中,更改为静态资源引用

<TextBox PlaceholderText="My PlaceholderText" Height="100" Width="500"
         HorizontalAlignment="Center" Style="{StaticResource NoHighlightTextBoxStyle}"
         BorderBrush="{Binding IsError, Converter={StaticResource BorderBrushColorConverter}}" 
         VerticalAlignment="Center" ></TextBox>

您不应将画笔绑定到
文本框的
边框画笔
,这意味着您已将固定画笔值设置为
边框画笔
。在xaml中使用
Binding
IValueConverter
时,它会将“MyBorderBrushEmmandatory”或“MyBorderBrush”资源中的
SolidColorBrush
值指定给
BorderBrush
,它是一个静态值,不会根据主题的更改而更改。简而言之,类似于将红色固定的
solidcolorbush
设置为
BorderBrush
,与动态主题资源无关

如果要在更改主题时更改
TextBox
BorderBrush
,只需将xaml
TextBox
绑定代码替换为主题资源引用:

<TextBox PlaceholderText="My PlaceholderText" Height="100" Width="500"
         HorizontalAlignment="Center" 
         BorderBrush="{ThemeResource MyBorderBrushMandatory}"
         VerticalAlignment="Center" ></TextBox>
MainPage.xaml.cs:

public sealed partial class MainPage : Page,INotifyPropertyChanged
{
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
        this.ActualThemeChanged += MainPage_ActualThemeChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void MainPage_ActualThemeChanged(FrameworkElement sender, object args)
    {
        IsError = !IsError;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.RequestedTheme = this.RequestedTheme == ElementTheme.Light ? ElementTheme.Dark : ElementTheme.Light;
    }

    private void OnPropertyChanged(string Name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(Name));
        }
    }

    private bool? isError=true;
    public bool? IsError
    {
        get
        {
            return isError;
        }
        set
        {
            isError = value;
            OnPropertyChanged("IsError");
        }
    }

}
---更新---

让我们谈谈你的样品。 首先,我们都知道,通过从App.xaml获取应用程序资源,可以设置
文本框的
边框笔刷。在Page2.xaml.cs中,使用以下代码

this.RequestedTheme = App.SelectedTheme;
这段代码只设置UIElement(及其子元素)用于确定资源的UI主题,也就是说,代码只设置页面的主题,而不设置应用程序。默认情况下,您的应用程序使用用户在Windows设置中设置的主题运行(设置>个性化设置>颜色>选择默认应用程序模式),您还可以将应用程序的属性设置为覆盖用户默认设置并指定使用的主题

作为部分:

主题只能在应用程序启动时设置,而不能在应用程序运行时设置。在应用程序运行时尝试设置RequestedTheme会引发异常(Microsoft.NET代码的NotSupportedException)。如果您允许用户选择属于应用程序UI的主题,则必须在应用程序数据中保存该设置,并在应用程序重新启动时应用该设置

所以当你换了t
<Application.Resources>
        <Color x:Key="MyBorder">#6b6b6b</Color>
        <SolidColorBrush x:Key="MyBorderBrush" Color="{StaticResource MyBorder}" />

        <Color x:Key="MyBorderMandatory">#ff0000</Color>
        <SolidColorBrush x:Key="MyBorderBrushMandatory" Color="{StaticResource MyBorderMandatory}" />

        <Color x:Key="MyBorderDark">#c85332</Color>
        <SolidColorBrush x:Key="MyBorderBrushDark" Color="{StaticResource MyBorderDark}" />

        <Color x:Key="MyBorderMandatoryDark">#FFD700</Color>
        <SolidColorBrush x:Key="MyBorderBrushMandatoryDark" Color="{StaticResource MyBorderMandatoryDark}" />
...
</Application.Resources>
public object Convert(object value, Type targetType, object parameter, string language)
{
    var isError = value as bool? ?? false;
    if (isError)
    {
        if (App.SelectedTheme == ElementTheme.Light)
        {
            return Application.Current.Resources["MyBorderBrushMandatory"] as SolidColorBrush;
        }
        else
        {
            return Application.Current.Resources["MyBorderBrushMandatoryDark"] as SolidColorBrush;
        }
    }
    else
    {
        return null;
    }
}
<TextBox PlaceholderText="My PlaceholderText" Height="100" Width="500"
         HorizontalAlignment="Center" Style="{StaticResource NoHighlightTextBoxStyle}"
         BorderBrush="{Binding IsError, Converter={StaticResource BorderBrushColorConverter}}" 
         VerticalAlignment="Center" ></TextBox>