(WPF) Как установить значение sys: Double в SystemFonts.MessageFontSize из ResourceDictionary?

Сценарий:

Я хочу использовать для своего приложения WPF 3 стандартных размера шрифта: BigFontSize, NormalFontSize и SmallFontSize. Это двойные значения, и они определены в словаре ресурсов как (где sys правильно определено):

<sys:Double x:Key="BigFontSize">18</sys:Double>
<sys:Double x:Key="NormalFontSize">14</sys:Double>
<sys:Double x:Key="SmallFontSize">12</sys:Double>

Это хорошо работает. Но я случайно выбрал 14 как нормальный размер. Я хочу получить размер шрифта, определенный системой для NormalFontSize. (Если это будет сделано, я могу использовать конвертер , как описано в здесь, чтобы получить BigFontSize и SmallFontSize относительно NormalFontSize)


Подсказка:

Из документации я обнаружил, что размер шрифта по умолчанию хранится в статическом свойстве (double) SystemFonts.MessageFontSize. Но что мне делать, чтобы получить это значение в словарь ресурсов? (Я знаю, что Binding или DynamicResource не могут быть применены. Но это статическое значение, так как я могу применить StaticResource или x:Static или что-то еще?)

я пытался

<sys:Double x:Key="XXXFontSize">
    <StaticResource ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>

а также

<sys:Double x:Key="XXXFontSize">
    <x:Static ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>

Оба из них, похоже, не работают (как и ожидалось). Я получаю сообщение об ошибке Cannot add content to object of type 'System.Double'.

Примечание.

  • Я не хочу делать это из кода, например из App (). (Возможно ли иметь код программной части для ResourceDictionary?)
  • Я не хочу заключать это в обобщенный стиль, на основе которого могут быть получены другие стили (с использованием BasedOn), потому что у меня есть несколько словарей ресурсов, и невозможно использовать DynamicResource с BasedOn
    То есть я не могу использовать

    <Style x:Key="BigFont" TargetType="{x:Type Control}"}>
        <Setter Property="Control.FontSize" 
                Value="{Binding Source={x:Static SystemFonts.MessageFontSize},
                                Converter={ . . . }" />
    </Style>
    

    Потому что, если у меня есть стиль в другом ResourceDictionary, скажем HeaderTextBlockStyle, тогда мне придется использовать BasedOn={DynamicResource BigFont}, что невозможно (я думаю)

Любая помощь будет принята с благодарностью.
Спасибо.

TAGS: WPF SystemFonts.MessageFontSize ResourceDictionary FontSize BasedOn DynamicResource.


person mg007    schedule 29.01.2010    source источник


Ответы (2)


Я сделал вот так ...

public partial class GlobalResources : ResourceDictionary
{
    public GlobalResources()
    {
        this.Add("GiantFontSize", SystemFonts.MessageFontSize * 2.5);
        this.Add("BigFontSize", SystemFonts.MessageFontSize * 1.5);
        this.Add("MediumFontSize", SystemFonts.MessageFontSize * 1.25);
        this.Add("NormalFontSize", SystemFonts.MessageFontSize);
        this.Add("SmallFontSize", SystemFonts.MessageFontSize * 0.85);
    }
}

... и работает как чудо !!! Я могу использовать эти ресурсы в том же (частичном) словаре ресурсов или из других словарей ресурсов, подобных этому ...

<Style ...>
    <Setter Property="FontSize"
            Value="{DynamicResource MediumFontSize}" />

    ...

</Style>

Я не знаю, "хорошая практика" это или нет (прокомментируйте, пожалуйста), я знаю только, что это работает .. !!!

person mg007    schedule 04.02.2010

Ознакомьтесь с этой статьей: Переопределить стили по умолчанию Это может быть то, что вы ищете.

person Joshua Cauble    schedule 29.01.2010
comment
Спасибо, Джошуа, за быстрый ответ! Статья интересная, но не совсем решает мою проблему. Я знаю, что мы можем переопределить стиль по умолчанию, но я хочу сохранить значение по умолчанию FontSize и сохранить его в ресурсе (типа double), чтобы его можно было использовать для вычисления относительного значения других двойных ресурсов (даже если это кажется мой следующий вопрос!) - person mg007; 30.01.2010
comment
Хм, ну, одна вещь, о которой я мог бы подумать, - это изменить ваш код, чтобы использовать конвертер. Затем вы можете установить Control.FontSize на объект преобразователя, который оценивается на основе элемента управления. Взгляните на это stackoverflow.com/questions/312044/ Это может предоставить альтернативу. Он не полностью включен в ресурс, но может позволить вам делать то, что вы пытаетесь сделать. - person Joshua Cauble; 01.02.2010
comment
Вы имеете в виду, что я должен привязать свойство шрифта каждого элемента управления к SystemFonts.MessageFontSize и преобразователю (предположим, FontSizeMapper), который принимает параметры B, N и S (для больших, нормальных и мелких) и соответственно возвращает размер шрифта? Да, это вариант, но не думаете ли вы, что это будет немного проще, если я инкапсулирую это в стиле элементов управления (как упоминалось в моем вопросе Note # 2) без использования BasedOn={...}? - person mg007; 01.02.2010
comment
То, что я думал, было больше похоже на установку свойства FontSize стилей, чтобы использовать преобразование для получения значения. Конечно, я предполагаю, что у вас есть какое-то глобальное значение, чтобы сказать, что я хочу переключить все на большое, маленькое и т. Д., И это не только для отдельного управления. Таким образом у вас может быть доступ к более широким переменным системного уровня из преобразователя и позволить преобразователю определять, что туда помещать. Если у меня будет возможность, я посмотрю, смогу ли я собрать образец и опубликовать его в своих исходных комментариях. - person Joshua Cauble; 01.02.2010
comment
Хорошо, беру обратно, это не так ясно, как я думал. Единственный жизнеспособный вариант, который я вижу, - это переопределить значение по умолчанию. Вы можете сделать это с помощью словарей ресурсов. Так что имейте словарь для каждого размера, который вы хотите, а затем объедините правильный. Посмотрите на переключение тем WPF / словарей ресурсов во время выполнения, чтобы получить общее представление. Я думаю, что это может быть самый простой способ добиться этого. - person Joshua Cauble; 01.02.2010
comment
Да, это сложно, и я начал верить, что это невозможно! На данный момент я не меняю код, но я не очень доволен выбранными мной числами (18 для больших и т. Д.). В любом случае, спасибо за прекрасные предложения :) - person mg007; 02.02.2010
comment
Самое близкое, что я получил, - это наличие словаря ресурсов, который переопределяет это значение для каждой разницы в размерах, которую вы хотите. Затем в моем стиле для каждого типа элемента управления установите размер шрифта для динамического ресурса и укажите статическое значение. Когда вы меняете словари, выполняя операции добавления / удаления, это изменяет ваш стиль. По-прежнему требует большой работы по укладке. - person Joshua Cauble; 02.02.2010
comment
Думаю, у меня есть ответ, на самом деле ответ был только в моем вопросе! Как упоминалось в разделе примечаний. Возможно ли иметь код программной части для ResourceDictionary? ... Да ... действительно возможно иметь частичный класс ResourceDictionary. Однако я нигде не видел примеров по этому поводу; Я только что сделал проб и ошибок, и кажется, что это возможно. Что вы думаете об этом @Joshua? (Я закачу код в ближайшее время) - person mg007; 03.02.2010