Как изменить цвет textblock wpf

In my WPF application, I have to keep on updating TextBlock background based on user conditions. TextBlock style is defined in App.xaml. If the background is too dark (Green/Blue) I want to set the foreground to white else black. How can I achieve this? I explored following two options:
  • Remove From My Forums
  • Question

  • In my WPF application, I have to keep on updating TextBlock background based on user conditions. TextBlock style is defined in App.xaml. If the background is too dark (Green/Blue) I want to set the foreground to white else black. How can I achieve this? I explored
    following two options:

    1. Via DataTriggers: In App.xaml:

    <Style TargetType="TextBlock">             
         <Setter Property="FontSize" Value="14"/>
         <Setter Property="FontStyle" Value="Normal"/>
         <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Background,PresentationTraceSources.TraceLevel=High}" Value="White">
                <Setter Property="Foreground" Value="Maroon"/>
            </DataTrigger>
         </Style.Triggers>
     </Style>

    This doesn’t seem to work. I never see an update in textblock’s foreground property. While debugging, I see the following for the binding: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    System.Windows.Data Warning: 72 : RelativeSource.Self found TextBlock (hash=61003640) System.Windows.Data Warning: 78 : BindingExpression (hash=6398298): Activate with root item TextBlock (hash=61003640) System.Windows.Data Warning: 107 : BindingExpression
    (hash=6398298): At level 0 using cached accessor for TextBlock.Background: DependencyProperty(Background) System.Windows.Data Warning: 104 : BindingExpression (hash=6398298): Replace item at level 0 with TextBlock (hash=61003640), using accessor DependencyProperty(Background)
    System.Windows.Data Warning: 101 : BindingExpression (hash=6398298): GetValue at level 0 from TextBlock (hash=61003640) using DependencyProperty(Background): SolidColorBrush (hash=58614288) System.Windows.Data Warning: 80 : BindingExpression (hash=6398298):
    TransferValue — got raw value SolidColorBrush (hash=58614288) System.Windows.Data Warning: 89 : BindingExpression (hash=6398298): TransferValue — using final value SolidColorBrush (hash=58614288) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    What is «SolidColorBrush (hash=58614288)»? Is it the Hex color code or hascode for the object of type SolidColorBrush?

    1. Using IValueConverter: Have not tried it since I don’t want to convert one value to another but change a UIElement’s property based on some other property change. Also, wouldn’t converters will give a performance hit since almost all UIElements use TextBlock
      internally to display data?

    Any help is highly appreciated.

    Thanks,

    RDV

    • Edited by

      Wednesday, August 28, 2013 10:59 PM
      Added Code

Answers

  • Hi,

    I have moved the same style which i defined inline to a global style in App.xaml. it seems to work fine for me.

    App.xaml

    <Application.Resources>
            <Style x:Key="TextBlockStyle" TargetType="TextBlock">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=Background.Color}" Value="White">
                        <Setter Property="Foreground" Value="Black"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=Background.Color}" Value="Red">
                        <Setter Property="Foreground" Value="White"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=Background.Color}" Value="Green">
                        <Setter Property="Foreground" Value="White"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Application.Resources>

    MainWindow.xaml

    <StackPanel x:Name="myStackPanel">
                    <TextBlock Text="Hai" Style="{StaticResource TextBlockStyle}"/>
                    <TextBlock Text="Bye" Style="{StaticResource TextBlockStyle}"/>
                    <TextBlock Text="Good" Style="{StaticResource TextBlockStyle}"/>
                    <Button Content="Red" Click="Button_Click"/>
                    <Button Content="White" Click="Button_Click"/>
                    <Button Content="Green" Click="Button_Click"/>
                </StackPanel>

    Code Behind(Button_Click event)

      private void Button_Click(object sender, RoutedEventArgs e)
            {
                var button = sender as Button;
                if (button.Content.Equals("Red"))
                {
                    foreach (var child in this.myStackPanel.Children)
                    {
                        if (child is TextBlock)
                        {
                            var textblock = child as TextBlock;
                            textblock.Background = new SolidColorBrush(Colors.Red);
                        }
                    }
                }
                if (button.Content.Equals("Green"))
                {
                    foreach (var child in this.myStackPanel.Children)
                    {
                        if (child is TextBlock)
                        {
                            var textblock = child as TextBlock;
                            textblock.Background = new SolidColorBrush(Colors.Green);
                        }
                    }
                }
                if (button.Content.Equals("White"))
                {
                    foreach (var child in this.myStackPanel.Children)
                    {
                        if (child is TextBlock)
                        {
                            var textblock = child as TextBlock;
                            textblock.Background = new SolidColorBrush(Colors.White);
                        }
                    }
                }
            }

    Outputs I got


    srithar

    • Marked as answer by
      RDV17
      Friday, August 30, 2013 8:28 PM

As far as I remember, in most cases classes like TextBlock, TextBox and many others take the text color from the TextElement.Foreground property. The property value is inherited throughout the visual tree, i.e. you may set it on the root element and have most of the text change its color. For example:

<Grid TextElement.Foreground="Red">
  <TextBlock Text="test"/>
</Grid>

In fact, the same is true even for labels: the setter in their default style simply sets the TextElement.Foreground to one of the system colors.

However, this is true only for the default state of controls. Altered states, like highlighting, are not inherited, but rather taken from the system colors, as Rachel has written.

UPDATE

The same is true for FontSize and FontFamily. They are properties of the TextElement class that have attached property usage. They inherit their values. Once you set a value on a visual tree item, all its children will get the same value. Unless they override it either by an explicit property assignment, or by style and so on.

Once again, text color font size and font family are governed by the value of TextElement.Foreground, TextElement.FontSize and TextElement.FontFamily attached dependency properties on a specific visual element.

Some controls, like Label explicitly set their Foreground to some brush. It happens so that the brush is one of the SystemColors. But it doesn’t have to be true for all controls. Others (TextBlock, TextBox, etc.) don’t override the property value and just use some default settings evaluated on startup. The same happens to FontSize and FontFamily. You do not need to set them wherever in order for them to work. That’s how WPF works.

Supposedly, the values depend on the system theme. I believe they are evaluated during the app startup. Perhaps they are configurable.

UPDATE 2

Answers to your new questions:

How does a TextBlock get its default color, if the client app doesn’t provide any style, either programmatically or through xaml?

It takes it from the inherited value of the TextElement.Foreground attached dependency property. By default it is inherited from the root visual element, which in turn is simply set to the default value of the dependency property (Brushes.Black). See also

How does a Label get its default color?

It takes it from the value of the TextElement.Foreground attached dependency property. Since its default style sets it to the {DynamicResource {x:Static SystemColors.ControlTextBrushKey}, it gets bound to the system color.

How does a TextBlock get its default font size and font family, if the client app doesn’t provide any style, either programmatically or through xaml?

The same as for its text color. MSDN says that for the default value of the font size is SystemFonts.MessageFontSize which depends on system settings. Font family is determined in similar way from SystemFonts.MessageFontFamily.
Both these default values are passed to the FrameworkPropertyMetadata constructor upon dependency property registration in the TextElement static constructor.

Going deeper: SystemFonts.MessageFontFamily and SystemFonts.MessageFontSize wrap internal SystemParameters.NonClientMetrics which in turn are retrieved from the WIN32 native SystemParametersInfo http://msdn.microsoft.com/en-us/library/ms724947. Thus the WPF is tightly integrated with all Windows UI stuff like themes, fonts, etc.

How does a Label get its default font size and font family?

The same as for TextBlock. Label derives from ContentControl which in turn derives from Control. Control class adds itself as an owner of the TextElement.FontFamily and TextElement.FontSize properties with the same default values.

See also:

Property Value Inheritance

UPDATE 3

You should understand the main idea: the values are inherited. It means they might be inherited from anywhere, from any control. You can tell exactly which one it is inherited from only for a certain logical tree structure. You change it a bit — and the colors change. Someone sets a property’s value explicitly — and all children will inherit the value. Therefore your questions make little practival sense. But they are still interesting from the perspective of undestanding the WPF.

Overriding default values

Although you cannot change the values of the SystemFonts properties (they are read-only), you don’t have to. To change the font size and family for the whole window, simply assign the desired values to the TextElement attached properties on the Window:

<Window TextElement.FontSize="20" TextElement.FontFamily="Century Gothic">
  ..
</Window>

and all controls that do not explicitly override the inheritance will receive the settings. For those that do override — you’ll have to override their default styles or even throw them away if they hard-code the values.

The same approach works for TextElement.Foreground (and Background and so on).

As far as I remember, in most cases classes like TextBlock, TextBox and many others take the text color from the TextElement.Foreground property. The property value is inherited throughout the visual tree, i.e. you may set it on the root element and have most of the text change its color. For example:

<Grid TextElement.Foreground="Red">
  <TextBlock Text="test"/>
</Grid>

In fact, the same is true even for labels: the setter in their default style simply sets the TextElement.Foreground to one of the system colors.

However, this is true only for the default state of controls. Altered states, like highlighting, are not inherited, but rather taken from the system colors, as Rachel has written.

UPDATE

The same is true for FontSize and FontFamily. They are properties of the TextElement class that have attached property usage. They inherit their values. Once you set a value on a visual tree item, all its children will get the same value. Unless they override it either by an explicit property assignment, or by style and so on.

Once again, text color font size and font family are governed by the value of TextElement.Foreground, TextElement.FontSize and TextElement.FontFamily attached dependency properties on a specific visual element.

Some controls, like Label explicitly set their Foreground to some brush. It happens so that the brush is one of the SystemColors. But it doesn’t have to be true for all controls. Others (TextBlock, TextBox, etc.) don’t override the property value and just use some default settings evaluated on startup. The same happens to FontSize and FontFamily. You do not need to set them wherever in order for them to work. That’s how WPF works.

Supposedly, the values depend on the system theme. I believe they are evaluated during the app startup. Perhaps they are configurable.

UPDATE 2

Answers to your new questions:

How does a TextBlock get its default color, if the client app doesn’t provide any style, either programmatically or through xaml?

It takes it from the inherited value of the TextElement.Foreground attached dependency property. By default it is inherited from the root visual element, which in turn is simply set to the default value of the dependency property (Brushes.Black). See also

How does a Label get its default color?

It takes it from the value of the TextElement.Foreground attached dependency property. Since its default style sets it to the {DynamicResource {x:Static SystemColors.ControlTextBrushKey}, it gets bound to the system color.

How does a TextBlock get its default font size and font family, if the client app doesn’t provide any style, either programmatically or through xaml?

The same as for its text color. MSDN says that for the default value of the font size is SystemFonts.MessageFontSize which depends on system settings. Font family is determined in similar way from SystemFonts.MessageFontFamily.
Both these default values are passed to the FrameworkPropertyMetadata constructor upon dependency property registration in the TextElement static constructor.

Going deeper: SystemFonts.MessageFontFamily and SystemFonts.MessageFontSize wrap internal SystemParameters.NonClientMetrics which in turn are retrieved from the WIN32 native SystemParametersInfo http://msdn.microsoft.com/en-us/library/ms724947. Thus the WPF is tightly integrated with all Windows UI stuff like themes, fonts, etc.

How does a Label get its default font size and font family?

The same as for TextBlock. Label derives from ContentControl which in turn derives from Control. Control class adds itself as an owner of the TextElement.FontFamily and TextElement.FontSize properties with the same default values.

See also:

Property Value Inheritance

UPDATE 3

You should understand the main idea: the values are inherited. It means they might be inherited from anywhere, from any control. You can tell exactly which one it is inherited from only for a certain logical tree structure. You change it a bit — and the colors change. Someone sets a property’s value explicitly — and all children will inherit the value. Therefore your questions make little practival sense. But they are still interesting from the perspective of undestanding the WPF.

Overriding default values

Although you cannot change the values of the SystemFonts properties (they are read-only), you don’t have to. To change the font size and family for the whole window, simply assign the desired values to the TextElement attached properties on the Window:

<Window TextElement.FontSize="20" TextElement.FontFamily="Century Gothic">
  ..
</Window>

and all controls that do not explicitly override the inheritance will receive the settings. For those that do override — you’ll have to override their default styles or even throw them away if they hard-code the values.

The same approach works for TextElement.Foreground (and Background and so on).

Текстовые элементы управления

Последнее обновление: 18.01.2016

TextBlock

Элемент предназначен для вывода текстовой информации, для создания простых надписей:

<StackPanel>
    <TextBlock>Текст1</TextBlock>
    <TextBlock Text="Текст2" />
</StackPanel>

Ключевым свойством здесь является свойство Text, которое задает текстовое содержимое. Причем в случае <TextBlock>Текст1</TextBlock>
данное свойство задается неявно.

С помощью таких свойств, как FontFamily, TextDecorations и др., мы можем настроить отображение текста. Однако мы можем задать и более сложное форматирование, например:

<TextBlock TextWrapping="Wrap">
    <Run FontSize="20" Foreground="Red" FontWeight="Bold">О</Run>
    <Run FontSize="16" Foreground="LightSeaGreen">негин был, по мненью многих...</Run>
</TextBlock>

TextBlock в WPF

Элементы Run представляют куски обычного текста, для которых можно задать отдельное форматирование.

Для изменения параметров отображаемого текста данный элемент имеет такие свойства, как LineHeight,
TextWrapping и TextAlignment.

Свойство LineHeight позволяет указывать высоту строк.

Свойство TextWrapping позволяет переносить текст при установке этого свойства TextWrapping="Wrap". По умолчанию это свойство имеет
значение NoWrap, поэтому текст не переносится.

Свойство TextAlignment выравнивает текст по центру (значение Center), правому (Right) или левому краю (Left): <TextBlock TextAlignment="Right">

Для декорации текста используется свойство TextDecorations, например, если TextDecorations="Underline", то текст будет подчеркнут.

Если нам вдруг потребуется перенести текст на другую строку, то тогда мы можем использовать элемент LineBreak:

<TextBlock>
	Однажды в студеную зимнюю пору
    <LineBreak />
    Я из лесу вышел
</TextBlock>

TextBox

Если TextBlock просто выводит статический текст, то этот элемент представляет поле для ввода текстовой информации.

Он также, как и TextBlock, имеет свойства TextWrapping, TextAlignment и TextDecorations.

С помощью свойства MaxLength можно задать предельное количество вводимых символов.

<TextBox MaxLength="250" TextChanged="TextBox_TextChanged">Начальный текст</TextBox>

В коде C# мы можем обработать событие изменения текста:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
	TextBox textBox = (TextBox)sender;
	MessageBox.Show(textBox.Text);
}

По умолчанию, если вводимый текст превышает установленные границы поля, то текстовое поле растет, чтобы вместить весь текст. Но визуально это не очень
хорошо выглядит. Поэтому, как и в случае с TextBlock, мы можем перенести непомещающийся текст на новую строку, установив свойство
TextWrapping=»Wrap».

Чобы переводить по нажатию на клавишу Enter курсор на следующую строку, нам надо установить свойство AcceptsReturn="True".

Также мы можем добавить полю возможность создавать табуляцию с помощью клавиши Tab, установив свойство AcceptsTab="True"

Для отображения полос прокрутки TextBox поддерживает свойства VerticalScrollBarVisibility и НоrizontalScrollBarVisibility:

<TextBox AcceptsReturn="True" Height="100" VerticalScrollBarVisibility="Auto" 
         HorizontalScrollBarVisibility="Auto">Начальный текст</TextBox>

Возможно, при создании приложения нам потребуется сделать текстовое поле недоступным для ввода (на время в зависимости от условий или вообще),
тогда для этого нам надо установить свойство IsReadOnly="True".

Для выделения текста есть свойства SelectionStart, SelectionLength и SelectionText.
Например, выделим программно текст по нажатию кнопки:

<StackPanel>
    <TextBox x:Name="textBox1" Height="100" SelectionBrush="Blue" />
    <Button Content="Выделить текст" Height="30" Width="100" Click="Button_Click" Margin="10" />
</StackPanel>

Обработчик нажатия кнопки:

private void Button_Click(object sender, RoutedEventArgs e)
{
    textBox1.SelectionStart = 5;
    textBox1.SelectionLength = 10;
    textBox1.Focus();
	// данное выражение эквивалентно
	//textBox1.Select(5, 10);
}

Проверка орфографии

TextBox обладает встроенной поддержкой орфографии. Чтобы ее задействовать, надо установить свойство SpellCheck.IsEnabled="True".
Кроме того, по умолчанию проверка орфографии распространяется только на английский язык, поэтому, если приложение заточено под другой язык, нам надо его
явным образом указать через свойство Language:

<DockPanel>
    <TextBox SpellCheck.IsEnabled="True" Language="ru-ru">Привет, как дила?</TextBox>
</DockPanel>

Проверка орфографии в WPF

Метка (Label)

Главной особенностью меток является поддержка мнемонических команд-клавиш быстрого доступа, которые передают фокус связанному элементу. Например,

<Label Target="{Binding ElementName=TextBox1}">_привет</Label>
<TextBox Name="TextBox1" Margin="0 30 0 0" Height="30" Width="100"></TextBox>

Теперь, нажав на клавишу «п», мы переведем фокус на связанное текстовое поле. При вызове приложения подчеркивание не отображается, чтобы отображать подчеркивание, надо нажать на клавишу Alt.
Тогда чтобы перевести фокус на связанное текстовое поле необходимо будет нажать сочетание Alt + «п».
Если не предполагается использование клавиш быстрого доступа, то для вывода обычной текста вместо меток лучше использовать элемент TextBlock.

PasswordBox

Элемент предназначен для ввода парольной информации. По сути это тоже текстовое поле, только для ввода символов используется маска.
Свойство PasswordChar устанавливает символ маски, отображаемый при вводе пароля. Если это свойство не задано, то по умолчанию
для маски символа используется черная точка.
Свойство Password устанавливает парольную строку, отображаемую по умолчанию при загрузке окна приложения.

<StackPanel>
    <PasswordBox PasswordChar="*" MinHeight="30" />
    <PasswordBox MinHeight="30" />
</StackPanel>

PasswordBox в WPF

RichTextBox

Для вывода текстового содержимого, насыщенного форматированием, графикой, предназначен RichTextBox. Можно даже сказать, что он выводит не
просто текст, а документы с более сложным форматированием, чем обычный TextBox. Более подробно о нем, а также как на его основе создать
простой текстовый редактор, мы поговорим в главе, посвященной документам.

Introduction
Setting a TextBlock’s Content
Formatting Text
Using Controls with Formatted Text

Introduction

In WPF there are two very similar controls Label and TextBlock, and I’m going to cover TextBlock and why its so useful. First, what is the TextBlock control? A first look at the Msdn documentation.

Provides a lightweight control for displaying small amounts of flow content.

Well, that doesn’t tell that much about the control. A more accurate description would be that its a lightweight control for displaying various forms of formatted text and controls in a flow layout. Specifically, the TextBlock control can contain other controls, and arbitrary text that you can format with different font styles, colors, and brushes. Because it can contain other controls, it is actually much more than a `Text`Block, and I’m not sure why they named it TextBlock considering.

Setting a TextBlock’s Content

For demonstration, I will start with a small WPF Windows Application that contains just a TextBlock control containing the text Hello World!.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top"> 
            Hello World!
        </TextBlock>
    </Grid>
</Window>

TextBlockDemo_HelloWorld

An empty window with a TextBlock

There are two ways you can set text for a TextBlock. The first is the most obvious, and that is to set the Text property.

<TextBlock Text="Hello World!" HorizontalAlignment="Stretch" VerticalAlignment="Top">

The second is by setting the inner value of the control like I did in the demo application. Both methods give the same result for displaying Hello World!, but only setting the inner value of the TextBlock control gives us access to the true potential of the control. The Text property itself can only be used to display an arbitrary System.String. Shown below is the source code from the TextBlock metadata of its Text property.

//
// Summary:
//     Gets or sets the text contents of a System.Windows.Controls.TextBlock.
//
// Returns:
//     The text contents of this System.Windows.Controls.TextBlock. Note that all
//     non-text content is stripped out, resulting in a plain text representation
//     of the System.Windows.Controls.TextBlock contents. The default is System.String.Empty.
[Localizability(LocalizationCategory.Text)]
public string Text { get; set; }

Because the TextBlock can contain multiple controls by using its inner value, we can add things like buttons or other controls.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top">
            Hello World!
            <Button Content="Click me!" />
        </TextBlock>
    </Grid>
</Window>

A TextBlock containing text along with a Button control.

One of the most common questions from those just entering the WPF world is why doesn’t the button display on a new line even though in the Xaml the Button element is on its own line? Placing elements on a new line doesn’t necessarily do anything, and for a TextBlock control, adding a new line is actually done using the LineBreak element.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top">
            Hello World!
            <LineBreak />
            <Button Content="Click me!" />
        </TextBlock>
    </Grid>
</Window>

A TextBlock control with text, a button, and a line break.

I won’t cover any more about nested controls in the TextBlock. Once you understand that a control can contain other controls, the rest depends on your understanding of understanding the layout and styling mechanisms of WPF. The usefulness of truly comes from the ability to format strings of text without using multiple controls.

Formatting Text

Formatting text is done using an element called a Run which is defined as a inline-level flow content element intended to contain a run of formatted or unformatted text. Using a Run, you can style seperate segments of text using colors, brushes, and styles.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <Run Foreground="Red">Hello</Run>
            <Run Foreground="Blue">World!</Run>
        </TextBlock>
    </Grid>
</Window>

A TextBlock containing the text ‘Hello World!’ split into two runs, one red and one blue.

You can see that it was very easy to style the text to be red and blue. Now let’s add a LinearGradientBrush to the second run and give it a larger font with a bold style.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <Run Foreground="Red">Hello</Run>
            
            <LineBreak />
            
            <Run Text="World!" FontSize="24pt" FontWeight="Bold">
                <Run.Foreground>
                    <LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
                        <GradientStop Offset="0" Color="Navy" />
                        <GradientStop Offset="1" Color="DodgerBlue" />
                    </LinearGradientBrush>
                </Run.Foreground>
            </Run>
        </TextBlock>
    </Grid>
</Window>

A TextBlock run with its Foreground set to a LinearGradientBrush

Just like the TextBlock, a Run can contain its text in either its Text property, or its inner value. Since we want to use its inner value to set some text effects, it was moved from the inner value to the Text property. The FontSize and FontWeight properties were also added, along with our Run.Foreground element that contains our linear gradient effect.

Using Controls with Formatted Text

Often times you may want to do something like have a piece of text actually contain a link to some resource. I had a need for this myself in one of my dialogs in my licensing modules; I need it to display a link to a product page. A TextBlock can contain both controls and runs, which makes for great flexibility. A Run however, cannot contain a control so its important to make note of that.

<Window x:Class="TextBlockDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <Run Text="This is some text containing a " />
            <Hyperlink NavigateUri="http://danderson.io/">link to a page.</Hyperlink>
        </TextBlock>
    </Grid>
</Window>

A TextBlock containing a HyperLink.

The cool thing about this is that because a HyperLink is its own control, it can contain its own styling and behaviors.

There’s not much else to say about the TextBlock because it really is a simple control. It’s just really flexible and when used correctly can be a very easy way to display lots of formatted text to a user. The ability to contain controls that can also have their own styles and behaviors is really cool, but I still think the WPF team should have chosen a better name than TextBlock, because its much more than just arbitrary text.

valun

6 / 6 / 2

Регистрация: 09.12.2014

Сообщений: 140

1

10.09.2016, 13:31. Показов 7565. Ответов 7

Метки нет (Все метки)


Есть label к определен стиль «SectionName»
но <Setter Property=»TextElement.Foreground» Value=»#FFFCEC1D»></Setter> не срабатывает, как его изменить?

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Style x:Key="Labels.SectionName" TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
        <!--<Setter Property="OverridesDefaultStyle" Value="True"/>-->
        <Setter Property="Foreground" Value="{StaticResource Brushes.SectionName}"/>
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="TextElement.Foreground" Value="#FFFCEC1D"></Setter>
        <Setter Property="Template">            
            <Setter.Value>
                <ControlTemplate>
                    <ContentPresenter 
                        x:Name="contentPresenter" 
                         Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Converters.ToUpperCase}}"
                        Focusable="False" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        Margin="3,5,0,5"
                        RecognizesAccessKey="True"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                    </ContentPresenter>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



MaxSlim

114 / 113 / 64

Регистрация: 03.06.2013

Сообщений: 582

11.09.2016, 22:42

2

valun, не специалист, но может так:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<Style x:Key="Labels.SectionName" TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
        <!--<Setter Property="OverridesDefaultStyle" Value="True"/>-->
        <Setter Property="Foreground" Value="{StaticResource Brushes.SectionName}"/>
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="TextElement.Foreground" Value="#FFFCEC1D"></Setter>
        <Setter Property="Template">            
            <Setter.Value>
                <ControlTemplate>
                    <ContentPresenter 
                        x:Name="contentPresenter" 
                         Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource Converters.ToUpperCase}}"
                        Focusable="False" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        Margin="3,5,0,5"
                        RecognizesAccessKey="True"
                        Foreground="{TemplateBinding TextElement.Foreground}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                    </ContentPresenter>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>



0



6 / 6 / 2

Регистрация: 09.12.2014

Сообщений: 140

12.09.2016, 01:01

 [ТС]

3

Ошибку выкидывает((



0



skilllab

294 / 234 / 58

Регистрация: 03.02.2011

Сообщений: 1,973

Записей в блоге: 1

12.09.2016, 07:32

4

valun, конечно не сработает. Вы же 2 раза фактически указываете Foreground

XML
1
2
3
<Setter Property="Foreground" Value="{StaticResource Brushes.SectionName}"/>
...
<Setter Property="TextElement.Foreground" Value="#FFFCEC1D"></Setter>

Миниатюры

Изменить цвет TextBlock в ContentPresenter
 



0



6 / 6 / 2

Регистрация: 09.12.2014

Сообщений: 140

12.09.2016, 09:42

 [ТС]

5

да тут хоть раз хоть два, без разницы. ContentPresrnter подставляет автоматически textblock для вывода текста и и вот именно этот textblock перекрывает все стили.



0



294 / 234 / 58

Регистрация: 03.02.2011

Сообщений: 1,973

Записей в блоге: 1

12.09.2016, 10:02

6

Цитата
Сообщение от valun
Посмотреть сообщение

без разницы

хмм..
сначала у вас в стиле цвет текста Brushes.SectionName, потом #FFFCEC1D
Я бы тоже растерялся какой именно выбрать для отображения.
Вы какой цвет то в итоге хотите в «автоматически представленном TextBlock»?



0



6 / 6 / 2

Регистрация: 09.12.2014

Сообщений: 140

12.09.2016, 23:52

 [ТС]

7

Brushes.SectionName и #FFFCEC1D это один и тот же цвет, хоть два хоть один раз указывал, толку не какого . Label отрисовывает белый текст так как contentpresenter автоматически отрисовывает через textblock



0



294 / 234 / 58

Регистрация: 03.02.2011

Сообщений: 1,973

Записей в блоге: 1

13.09.2016, 07:36

8

Цитата
Сообщение от valun
Посмотреть сообщение

Label отрисовывает белый текст так как contentpresenter автоматически отрисовывает через textblock

Так у вас в Label заныкан TextBlock?

Ладушки. Дальше сами))) Моё вангование не распространяется так далеко.

Миниатюры

Изменить цвет TextBlock в ContentPresenter
 



1



Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить цвет text decoration
  • Как изменить цвет system bar android
  • Как изменить цвет svg через css при наведении
  • Как изменить цвет svg через css img
  • Как изменить цвет svg через css background

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии