Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
60 views
in Technique[技术] by (71.8m points)

c# - How to change the margin of a TextBlock without moving the text?

Whenever I try to resize a TextBlock, per usual, the text moves with it. Is there a way to circumvent this behavior so I can resize the background without moving the text?

I've fiddled with a plethora of settings, asked around on a few chats, but came up dry.

Alternatively, is there a way to place the text in the absolute center of the TextBlock? Text doesn't move when I resize the TextBlock downwards, but any other direction, it moves. I've worked with horizontal & vertical alignments of the text, etc, but also came up dry.

question from:https://stackoverflow.com/questions/65854038/how-to-change-the-margin-of-a-textblock-without-moving-the-text

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a test code that might do what you want or at least give you some ideas. In the bottom part of the screen, you can change the margin, width and height of the text block in the upper part.

The code is calculating the move of the left/top position of the text block. The Padding of the text block is then set to compensate for that move. If the text goes outside the left or top side of the text block, padding is set to 0 and it will follow the text block. You have to take care of what to do if the text goes outside the right / bottom of the text block.

The calculation is done in the LayoutUpdated event handler which is called after all layout arrangements are done in the panel.

XAML:

<Grid x:Name="grid" LayoutUpdated="Grid_LayoutUpdated">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBlock x:Name="textBlock" Text="Test" Height="50" Width="100"/>
    <StackPanel Grid.Row="1">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Margin" Width="100" Margin="5"/>
            <TextBox Text="{Binding Margin, ElementName=textBlock, Mode=TwoWay}" Margin="5"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
                <TextBlock Text="Width" Width="100" Margin="5"/>
                <TextBox Text="{Binding Width, ElementName=textBlock}" Margin="5"/>
            </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Height" Width="100" Margin="5"/>
            <TextBox Text="{Binding Height, ElementName=textBlock}" Margin="5"/>
        </StackPanel>
    </StackPanel>
</Grid>

Code behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        lastTextBlockPos = textBlock.PointToScreen(new Point());
        initiateReady = true;
    }

    bool initiateReady = false;
    Point lastTextBlockPos = new Point();
    private void Grid_LayoutUpdated(object sender, EventArgs e)
    {
        if (initiateReady)
        {
            Point tp = textBlock.PointToScreen(new Point());
            if (tp != lastTextBlockPos)
            {
                //Calculate how much the top left corner of the text block moved during layout.
                double left = textBlock.Padding.Left - tp.X + lastTextBlockPos.X;
                double top = textBlock.Padding.Top - tp.Y + lastTextBlockPos.Y;

                //Set the padding to move the text inside the text block
                //If outside the text block, set to left, top most position
                //TODO: take care of when the text is outside on the right, bottom side
                Thickness tn = new Thickness()
                {
                    Left = left >= 0 ? left : 0,
                    Top = top >= 0 ? top : 0,
                };
                textBlock.Padding = tn;
                lastTextBlockPos = tp;

                //Showing TextBlock bounds for test
                Point gp = grid.PointToScreen(new Point());
                RectangleGeometry myRectangleGeometry = new RectangleGeometry();
                myRectangleGeometry.Rect = new Rect(tp.X - gp.X, tp.Y - gp.Y, textBlock.ActualWidth, textBlock.ActualHeight);
                Path myPath = new Path();
                myPath.Data = myRectangleGeometry;
                myPath.Stroke = Brushes.Goldenrod;
                myPath.StrokeThickness = 2;
                Grid.SetColumn(myPath, 0);
                Grid.SetRow(myPath, 0);
                Path old = grid.Children.OfType<Path>().FirstOrDefault();
                if (old != null) grid.Children.Remove(old);
                grid.Children.Add(myPath);
            }
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...