簡體   English   中英

UWP RichEditBox 在深色模式下保存並在淺色模式下打開時出現文本顏色問題

[英]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

  1. 確保您的設備主題為“黑暗”。
  2. 運行應用程序並將一些文本添加到 RichEditBox 中(頂部的文本塊和按鈕只是為了確保應用程序在頁面加載時不會自動聚焦在richeditbox 上)。

圖 1

圖 2

  1. 單擊屏幕上的其他位置以從richeditbox 中釋放焦點,然后關閉應用程序。
  2. 再次運行應用程序,您會注意到之前輸入的文本已經按預期出現,現在關閉應用程序。

圖 3

  1. 將您設備的主題設置為“Light”並再次運行應用程序,現在您會注意到richeditbox 似乎是空的。

圖 4

  1. 但實際上它不是空的,問題是文本顏色是白色的,就像richeditbox的顏色一樣,而文本顏色在淺色主題中應該是黑色的。 這可以通過選擇帶有 cursor 的文本並注意突出顯示的文本來證明。

圖 5

筆記

每次您更改某些內容並嘗試再次測試整個流程時,只需確保更改LoadedTextChanged事件中的字符串,以確保保存並稍后加載全新的RTF值,加載和文本更改事件中的鍵必須始終匹配,並且每次您想從第 1 步開始時都應更改。

圖 6

代碼

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 看起來更好用黑色背景,其他有白色等)

1.更改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
}

我已經對此進行了測試,這似乎也有效。

2.更改RTF

一種更底層的方法是在從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.xamlPage header 中的RequestedTheme屬性設置為LightDark

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM