[英]UWP RichEditBox text color issue when saved in dark mode and opened in light mode
基本上在我的應用程序中,我有一個RichEditBox需要將其數據保存在TextChanged事件中並從保存的設置OnLoaded事件中加載文本,經過數周的實驗,我能夠在一個最小的應用程序中重現該問題供你們測試。
目標:最終,無論我使用深色還是淺色主題將 RTF 文本保存在這個豐富的編輯框中,每當它再次以任何主題加載時,它都應該在深色和淺色主題中顯示正確的文本顏色。 並且在運行應用程序期間,如果用戶更改其設備的主題,文本顏色也應按預期更改。 我不確定如何在此處保存 rtf 文本,它可能會忽略文本顏色?
在這里重現錯誤: https://github.com/touseefbsb/RichEditBoxColorBug
每次您更改某些內容並嘗試再次測試整個流程時,只需確保更改Loaded和TextChanged事件中的鍵字符串,以確保保存並稍后加載全新的RTF值,加載和文本更改事件中的鍵必須始終匹配,並且每次您想從第 1 步開始時都應更改。
Xaml
<StackPanel>
<TextBlock>abc</TextBlock>
<Button>abc</Button>
<RichEditBox
x:Name="REB"
Height="60"
AcceptsReturn="True"
BorderThickness="0"
Loaded="REB_Loaded"
PlaceholderText="placeholder."
TextChanged="REB_TextChanged"
TextWrapping="Wrap" />
</StackPanel>
代碼背后
private void REB_Loaded(object sender, RoutedEventArgs e)
{
var localSettings = ApplicationData.Current.LocalSettings;
var localValue = localSettings.Values["ts5"] as string; // Change the key value on every new test
var text = string.IsNullOrEmpty(localValue) ? string.Empty : localValue;
REB.Document.SetText(TextSetOptions.FormatRtf, text);
}
private void REB_TextChanged(object sender, RoutedEventArgs e)
{
var localSettings = ApplicationData.Current.LocalSettings;
REB.Document.GetText(TextGetOptions.FormatRtf, out var tmpNar);
if (!string.IsNullOrEmpty(tmpNar) && !string.IsNullOrWhiteSpace(tmpNar))
{
localSettings.Values["ts5"] = tmpNar; // Change the key value on every new test
}
}
Windows 10 器件版本:1903
項目目標和最小 sdk 版本:1903
我在嘗試將 RTF 從RichEditBox
轉換為 HTML 時遇到了類似的問題。
只要我們假設您不允許更改字體顏色,這並不難。 如果您允許通過文檔更改字體顏色,這兩個建議的選項也可以工作,但這會帶來很多工作和權衡(即,當在黑暗中顯示它們時,您是否反轉在淺色主題中選擇的 colors?,某些 colors 看起來更好用黑色背景,其他有白色等)
ITextDocument
這個選項非常簡單並且效果很好。 在RichEditBox
下方有一個包含實際文本的ITextDocument
(通過RichEditBox.Document
訪問)。 設置完本文檔的文本后,您還可以設置字體顏色(甚至可以通過這種方式更改文本某些部分的字體顏色):
REB_Loaded
private void REB_Loaded(object sender, RoutedEventArgs e)
{
var localSettings = ApplicationData.Current.LocalSettings;
var localValue = localSettings.Values["ts4"] as string;
var text = string.IsNullOrEmpty(localValue) ? string.Empty : localValue;
REB.Document.SetText(TextSetOptions.FormatRtf, text);
// Select all text currently in the RichtEditBox
// and make it white or black depending on the currently requested theme
REB.Document.GetRange(0, text.Length).CharacterFormat.ForegroundColor =
Window.Current.Content is FrameworkElement fe
? fe.ActualTheme == ElementTheme.Dark
? Windows.UI.Colors.White
: Windows.UI.Colors.Black
: Windows.UI.Colors.Black; // Assume light theme if actual theme cannot be determined
}
我已經對此進行了測試,這似乎也有效。
一種更底層的方法是在從LocalSettings
加載原始 RTF 之后以及在設置RichEditBox
的文本之前更改原始 RTF。 如果您檢查原始 RTF,您會看到如下內容:
{\rtf1\fbidis\ansi\ansicpg1252\deff0\nouicompat\deflang2057{\fonttbl{\f0\fnil\fcharset0 Segoe UI;}{\f1\fnil Segoe UI;}}
{\colortbl ;\red255\green255\blue255;}
{\*\generator Riched20 10.0.19041}\viewkind4\uc1
\pard\tx720\cf1\f0\fs21\lang1033 test text\f1\par}
這里要注意的是第二行: {\colortbl...}
,這部分定義了字體顏色。 如果您現在只是將 255 更改為 0,則您將字體從白色更改為黑色。 我已經編寫了兩種擴展方法,並且您的代碼中的快速測試似乎有效:
擴展class
public static class Extensions
{
public static string ConvertWhiteTextToBlack(this string s)
=> s.Replace("\\red255\\green255\\blue255", "\\red0\\green0\\blue0");
public static string ConvertBlackTextToWhite(this string s)
=> s.Replace("\\red0\\green0\\blue0", "\\red255\\green255\\blue255");
}
REB_Loaded
private void REB_Loaded(object sender, RoutedEventArgs e)
{
var localSettings = ApplicationData.Current.LocalSettings;
var localValue = localSettings.Values["ts4"] as string;
var text = string.IsNullOrEmpty(localValue) ? string.Empty : localValue;
System.Diagnostics.Debug.WriteLine("[REB_Loaded (start)]" + text);
// Make black text white if dark theme is requested
text = Window.Current.Content is FrameworkElement fe
? fe.ActualTheme == ElementTheme.Light
? text.ConvertWhiteTextToBlack()
: text.ConvertBlackTextToWhite()
: text.ConvertWhiteTextToBlack(); // Assume light theme if actual theme cannot be determined
System.Diagnostics.Debug.WriteLine("[REB_Loaded (end)]" + text);
REB.Document.SetText(TextSetOptions.FormatRtf, text);
}
PS 我希望這些解決方案也適用於您的 MVCE 之外和您的主應用程序。 如果沒有回復,我會盡力幫助你。
PPS 您無需更改整個 PC 主題即可將應用程序從暗變為亮。 相反,只需將MainPage.xaml
中Page
header 中的RequestedTheme
屬性設置為Light
或Dark
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.