Ответ 1
Вы все еще можете использовать конвертер, просто установите значение text в источнике привязки:
<TextBlock Text="{Binding Source={StaticResource String1}, Converter ={StaticResource myConverter}}"/>
Я хочу, чтобы все тексты в TextBlock
, Label
, MenuItem.Header
отображались в верхнем регистре.
Строки взяты из ResourceDictionary
например:
<TextBlock Text="{StaticResource String1}"/>
<MenuItem Header="{StaticResource MenuItemDoThisAndThat}"/>
и т.д.. (также для Label
и других элементов управления)
Я не могу использовать конвертер значений, потому что нет привязки. Я не хочу, чтобы верхний регистр строк был в самом словаре.
Вы все еще можете использовать конвертер, просто установите значение text в источнике привязки:
<TextBlock Text="{Binding Source={StaticResource String1}, Converter ={StaticResource myConverter}}"/>
Вместо использования конвертера вы можете использовать тег CharacterCasing в TextBox, но в вашем случае он не работает с TextBlock.
<TextBox CharacterCasing="Upper" Text="{StaticResource String1}" />
Я думаю, что это будет работать для вас
<TextBlock Text='{StaticResource String1}' Typography.Capitals="AllSmallCaps"/>
Для перечислений прописных букв https://msdn.microsoft.com/en-us/library/system.windows.fontcapitals(v=vs.110).aspx
Чтобы ответить Peter (мое редактирование было отклонено), вы можете использовать такой конвертер:
С#
public class CaseConverter : IValueConverter
{
public CharacterCasing Case { get; set; }
public CaseConverter()
{
Case = CharacterCasing.Upper;
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var str = value as string;
if (str != null)
{
switch (Case)
{
case CharacterCasing.Lower:
return str.ToLower();
case CharacterCasing.Normal:
return str;
case CharacterCasing.Upper:
return str.ToUpper();
default:
return str;
}
}
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML:
<TextBlock Text="{Binding Source={StaticResource String1}, Converter ={StaticResource myCaseConverter}}"/>
Для этого я создал прикрепленное свойство и конвертер. Вероятно, у вас уже есть конвертер, поэтому замените мою ссылку на CaseConverter на любую вашу реализацию.
Вложенное свойство - это просто логическое значение, которое вы задаете, если хотите, чтобы оно было в верхнем регистре (вы, очевидно, могли бы расширять его, а не перечислить для выбора стилей). Когда свойство изменяется, оно восстанавливает свойство TextBlock Text по мере необходимости, добавляя в конвертер.
Возможно, потребуется немного больше работы, когда свойство уже связано - мое решение предполагает простое связывание пути. Но, возможно, также потребуется дублировать источник и т.д. Однако я почувствовал, что этого примера достаточно, чтобы понять мою точку зрения.
Здесь вложенное свойство:
public static bool GetUppercase(DependencyObject obj)
{
return (bool)obj.GetValue(UppercaseProperty);
}
public static void SetUppercase(DependencyObject obj, bool value)
{
obj.SetValue(UppercaseProperty, value);
}
// Using a DependencyProperty as the backing store for Uppercase. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UppercaseProperty =
DependencyProperty.RegisterAttached("Uppercase", typeof(bool), typeof(TextHelper), new PropertyMetadata(false, OnUppercaseChanged));
private static void OnUppercaseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBlock txt = d as TextBlock;
if (txt == null) return;
var val = (bool)e.NewValue;
if (val)
{
// rebind the text using converter
// if already bound, use it as source
var original = txt.GetBindingExpression(TextBlock.TextProperty);
var b = new Binding();
if (original != null)
{
b.Path = original.ParentBinding.Path;
}
else
{
b.Source = txt.Text;
}
b.Converter = new CaseConverter() { Case = CharacterCasing.Upper };
txt.SetBinding(TextBlock.TextProperty, b);
}
}
Это не строго отвечает на вопрос, но дает трюк, чтобы вызвать тот же эффект.
Я считаю, что многие находят свой путь здесь, смотрят, как это сделать со стилем. TextBlock немного сложнее здесь, потому что это не элемент управления, а элемент FrameworkElement, и поэтому вы не можете определить шаблон для выполнения трюка.
Необходимость использования всего текста в верхнем регистре наиболее вероятна для заголовков или чего-то подобного, когда использование Label оправдано. Мое решение было:
<!-- Examples of CaseConverter can be found in other answers -->
<ControlTemplate x:Key="UppercaseLabelTemplate" TargetType="{x:Type Label}">
<TextBlock Text="{TemplateBinding Content, Converter={StaticResource CaseConverter}}" />
</ControlTemplate>
<Style x:Key="UppercaseHeadingStyle"
TargetType="{x:Type Label}">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Template" Value="{StaticResource UppercaseLabelTemplate}" />
</Style>
<!-- Usage: -->
<Label Content="Header" Style="{StaticResource UppercaseHeadingStyle}" />
Обратите внимание, что это отключает некоторые действия по умолчанию Label и работает только для текста, поэтому я бы не определил это как значение по умолчанию (никто, вероятно, не хочет, чтобы все метки были прописными буквами в любом случае). И, конечно, вы должны использовать Label вместо TextBlock, когда вам нужен этот стиль. Также я бы не использовал это внутри других шаблонов, но только строго как стиль темы.
Вы можете записать все входные данные в элементы управления TextBox со следующим свойством:
<TextBox CharacterCasing="Upper"
Чтобы применить ко всем элементам управления TextBox во всем приложении, создайте стиль для всех элементов управления TextBox:
<Style TargetType="{x:Type TextBox}">
<Setter Property="CharacterCasing" Value="Upper"/>
</Style>