Search code examples
wpfxaml

How to get the rendered font size of a textblock wrapped in a viewbox


There is a textblock (tb1) and a textblock (tb2) wrapped in a viewbox. When the layout size of tb2 changes, its font will also change due to the effect of the viewbox. I want to set the font size of tb1 to be the same as tb2 even if the layout size changes. However, after my testing, the font size attribute of tb2 has never changed. I believe that changing the actual font size of tb2 is caused by the viewbox and will not change the font size property value of tb2. However, I still cannot find a way to make the font size of tb1 follow tb2. Here is my code:

<Window x:Class="LiveCharts2Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LiveCharts2Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*"/>
            <RowDefinition Height="47*"/>
            <RowDefinition Height="338*"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="tb1" Grid.Row="0" Grid.Column="0" Text="apple" />
        <Viewbox Stretch="Uniform" Grid.Row="1" Grid.Column="0">
            <TextBlock x:Name="tb2" Text="testtesttesttesttesttesttesttesttesttest" LayoutUpdated="tb2_LayoutUpdated" />
        </Viewbox>
    </Grid>
</Window>
using System.Windows;

namespace LiveCharts2Test
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(tb1.FontSize);
            System.Diagnostics.Debug.WriteLine(tb2.FontSize);
        }

        private void tb2_LayoutUpdated(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(tb2.FontSize);
        }
    }
}

the environment is WPF(.net6.0)


Solution

  • After Gerry's reminder, I came up with the correct method: when the size of the viewbox changes, I get its content scaling factor, and then multiply the font size of tb2 by this factor,the code as following:

    private void viewbox_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        var child = VisualTreeHelper.GetChild(viewbox, 0) as ContainerVisual;
        var scale = child.Transform as ScaleTransform;
        tb1.FontSize = tb2.FontSize * scale.ScaleX;
    }