Search code examples
c#wpfclickformattextblock

Changing the formatting of clicked text in a textblock


I have a textBlock to which I've added some text e.g. as follows:

textBlock1.Inlines.Add(new Run("One "));
textBlock1.Inlines.Add(new Run("Two "));
textBlock1.Inlines.Add(new Run("Three "));

How can I add a click event that changes the color of the text of the inline that has been clicked?

e.g. if "One" is clicked I'd like it to have a red font; then if "Two" is clicked, I'd like "One" to be black again, and "Two" to be red, so that the color of the last word clicked is red.

I'm fairly new to programming with c# and wpf.

Thanks for your help


Solution

  • Something like this should do the trick

         public MainWindow()
        {
            InitializeComponent();
            textBlock1.Inlines.Add(new Run("One "));
            textBlock1.Inlines.Add(new Run("Two "));
            textBlock1.Inlines.Add(new Run("Three "));
        }
    
        private SolidColorBrush _blackBrush = new SolidColorBrush(Colors.Black);
        private SolidColorBrush _redBrush = new SolidColorBrush(Colors.Red);
        private Run _selectedRun;
    
        private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var run = e.OriginalSource as Run;
            if (run != null)
            {
                if (_selectedRun != null)
                {
                    _selectedRun.Foreground = _blackBrush;
                    if (_selectedRun == run)
                    {
                        return;
                    }
                }
                run.Foreground = _redBrush;
                _selectedRun = run;
            }
        }
    

    But you will have to handle click with "MouseDown" or "MouseUp" as Textblock does not have Click event

    To color one at a certain index this is a quick example.

    private void ColorInlineAtIndex(InlineCollection inlines, int index, Brush brush)
    {
        if (index <= inlines.Count - 1)
        {
              inlines.ElementAt(index).Foreground = brush;
        }
    }
    

    Usage:

     ColorInlineAtIndex(textBlock1.Inlines, 2, new SolidColorBrush(Colors.Blue));
    

    Find position:

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        var run = e.OriginalSource as Run;
        if (run != null)
        {
            int position = (sender as TextBlock).Inlines.ToList().IndexOf(run);
        }
    }