Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6980855
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T18:04:50+00:00 2026-05-27T18:04:50+00:00

A picture is worth a thousand words – so here is the existing against

  • 0

A picture is worth a thousand words – so here is the existing against the desirable:

enter image description here

This is what I’ve tried w/o success:

 public MainWindow()
    {
        InitializeComponent();
        TextBlock txt = new TextBlock();
        txt.Text = "asdsahd sakh uj";
        txt.Background = Brushes.LightBlue;
        Canvas.SetLeft(txt, 100);
        container.Children.Add(txt);


        Line line = new Line();
        line.SetBinding(Line.X1Property, new Binding("Canvas.Left") {ElementName = "txt"});
        line.X2 = line.X1;
        line.Y1 = 0;
        line.Y2 = 100;
        line.StrokeThickness = 2;
        container.Children.Add(line);
    }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T18:04:51+00:00Added an answer on May 27, 2026 at 6:04 pm

    In the solution below, I assume that your Canvas has a height and width that can change at runtime, and that your TextBlock can also have a height and width that change dynamically as well. The approach looks complicated, but its not. Of course doing this in XAML would be much, much more readable:

    1. Create a TextBlock add to canvas.
    2. Create a Line add to canvas.
    3. Use a MultiBinding to compute the Canvas.Left property for the TextBlock. If either the width of the Canvas or the TextBlock changes, this binding will re-evaluate and the IMultiValueConverter will provide a new value. The value of Canvas.Left for the TextBlock should be: Canvas.ActualWidth/2 – TextBlock.ActualWidth/2.
    4. To the same as in step 3, but this time for the Line.
    5. Use a MultiBinding to compute the Line.Y2 property for the Line. Assuming you want to draw the line to the bottom edge of the Canvas. To compute this: Canvas.ActualHeight – TextBlock.ActualHeight. The binding will re-evaluate if either change and the IMultiValueConverter will provide a new value.
    6. Use a Binding to set the Canvas.Top property on the Line. In this example, the Line is drawn immediately below the TextBlock, so we can just bind to TextBlock.ActualHeight.

    TextBlock and Line Creation

        public MainWindow()
        {
            InitializeComponent();
    
            // Create TextBlock and Line
            var textBlock = new TextBlock {Text = "123456"};
            var line = new Line { StrokeThickness = 2, Stroke = new SolidColorBrush { Color = Colors.Black }, Y1 = 0 };
            myCanvas.Children.Add(textBlock);
            myCanvas.Children.Add(line);
    
            // Setup bindings
            InitializeTextBlockCanvasLeftBinding(myCanvas, textBlock);
            InitializeLineCanvasLeftBinding(myCanvas, line);
            InitializeLineY2Binding(myCanvas, textBlock, line);
            InitializeLineCanvasTopBinding(myCanvas, textBlock, line);
        }
    
        private void InitializeLineCanvasTopBinding(Canvas canvas, TextBlock textBlock, Line line)
        {
            var textBlockActualHeightBinding = new Binding
            {
                Source = textBlock,
                Path = new PropertyPath("ActualHeight"),
            };
    
            BindingOperations.SetBinding(line, Canvas.TopProperty, textBlockActualHeightBinding);
        }
    
        private void InitializeLineY2Binding(Canvas canvas, TextBlock textBlock, Line line)
        {
            var canvasActualHeightBinding = new Binding
            {
                Source = myCanvas,
                Path = new PropertyPath("ActualHeight"),
            };
    
            var textBlockActualHeightBinding = new Binding
            {
                Source = textBlock,
                Path = new PropertyPath("ActualHeight"),
            };
    
            var lineY2MultiBinding = new MultiBinding { Converter = new LineY1MultiConverter() };
            lineY2MultiBinding.Bindings.Add(textBlockActualHeightBinding);
            lineY2MultiBinding.Bindings.Add(canvasActualHeightBinding);
    
            BindingOperations.SetBinding(line, Line.Y2Property, lineY2MultiBinding);
        }
    
        private void InitializeLineCanvasLeftBinding(Canvas canvas, Line line)
        {
            var lineActualWidthBinding = new Binding
            {
                Source = line,
                Path = new PropertyPath("ActualWidth"),
            };
    
            var canvasActualWidthBinding = new Binding
            {
                Source = myCanvas,
                Path = new PropertyPath("ActualWidth"),
            };
    
            var lineLeftMultiBinding = new MultiBinding { Converter = new CanvasLeftCenterMultiConverter() };
            lineLeftMultiBinding.Bindings.Add(lineActualWidthBinding);
            lineLeftMultiBinding.Bindings.Add(canvasActualWidthBinding);
    
            BindingOperations.SetBinding(line, Canvas.LeftProperty, lineLeftMultiBinding);
        }
    
        private void InitializeTextBlockCanvasLeftBinding(Canvas canvas, TextBlock textBlock)
        {
            var textBlockActualWidthBinding = new Binding
            {
                Source = textBlock,
                Path = new PropertyPath("ActualWidth"),
            };
    
            var canvasActualWidthBinding = new Binding
            {
                Source = myCanvas,
                Path = new PropertyPath("ActualWidth"),
            };
    
            var textBlockLeftMultiBinding = new MultiBinding { Converter = new CanvasLeftCenterMultiConverter() };
            textBlockLeftMultiBinding.Bindings.Add(textBlockActualWidthBinding);
            textBlockLeftMultiBinding.Bindings.Add(canvasActualWidthBinding);
    
            BindingOperations.SetBinding(textBlock, Canvas.LeftProperty, textBlockLeftMultiBinding);
        }
    

    MultiConverter to compute the length of the line

    public class LineY1MultiConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values != null && values.Length == 2 && values[0] is double && values[1] is double)
            {
                var canvasHeight = (double)values[1];
                var textBlockHeight = (double) values[0];
                return canvasHeight - textBlockHeight;
            }
    
            return DependencyProperty.UnsetValue;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    MultiConverter to center elements horizontally on the Canvas

    public class CanvasLeftCenterMultiConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values != null && values.Length == 2 && values[0] is double && values[1] is double)
            {
                var canvasMiddle = (double)values[1]/2;
                var elementHalf = (double) values[0]/2;
                return canvasMiddle - elementHalf;
            }
    
            return DependencyProperty.UnsetValue;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Edit

    To make the above code more clear – it really is just a 1-to-1 translation of the following XAML (using the MultiValueConverters from above):

        <Canvas x:Name="myCanvas" Background="Pink">
            <TextBlock x:Name="myTextBlock" Text="1234567890">
                <Canvas.Left>
                     <MultiBinding Converter="{l:CanvasLeftCenterMultiConverter}">
                        <Binding RelativeSource="{RelativeSource Mode=Self}" Path="ActualWidth" />
                        <Binding ElementName="myCanvas" Path="ActualWidth" />
                    </MultiBinding>
                </Canvas.Left>
            </TextBlock>
            <Line StrokeThickness="2" Stroke="Black" Canvas.Top="{Binding ElementName=myTextBlock, Path=ActualHeight}" Y1="0">
                <Line.Y2>
                    <MultiBinding Converter="{l:LineY1MultiConverter}">
                        <Binding ElementName="myTextBlock" Path="ActualHeight" />
                        <Binding ElementName="myCanvas" Path="ActualHeight" />
                    </MultiBinding>
                </Line.Y2>
                <Canvas.Left>
                    <MultiBinding Converter="{l:CanvasLeftCenterMultiConverter}">
                        <Binding RelativeSource="{RelativeSource Mode=Self}" Path="ActualWidth" />
                        <Binding ElementName="myCanvas" Path="ActualWidth" />
                    </MultiBinding>
                </Canvas.Left>
            </Line>
        </Canvas>
    

    As you can see – if the canvas size changes, the text size changes, or the line thickness changes, the bindings ensure new values for Canvas.Left and Canvas.Top are computed.

    Hope this helps!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

A picture is worth a thousand words, and I am guessing that the pictures
A picture is worth a thousand words, so ultimately, my question is how can
A picture is worth a thousand words and so I'll start off with it
A picture's worth a thousand words... For a bit more background, I have a
A picture is worth a thousand words: The app is setup for full screen
Because picture (or example) is worth more than thousand words, I'll use an example:
A picture is supposed to be worth a 1000 words, so let's see if
A picture says more than a thousand words. As you can see, my fill
Don't really know how to formulate the question. A picture is worth a thousand
Sorry for the length, but a picture is worth 1000 words: In ASP.NET MVC

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.