Search code examples
c#wpfuser-controlsbordertextblock

TextBlock in UserControl not displaying text


I'm trying to create a Nonogram (aka PuzzleCross) puzzle grid in C#/WPF, and have created two UserControls to contain the row and column keys. Each UserControl consists of a Border containing a TextBlock, with a DependencyProperty named TextControl to make the Text property accessible outside of the UserControl. Everything works fine except that the text isn't actually displayed when run. The TextControl contains the correct text, as tested with a MouseDown event and a MessageBox, but for some reason the text just isn't there.

Can anyone help me figure out what I'm missing? I have a feeling it's a simple thing, but I'm just not seeing it.

Horizontal UserControl:

    <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" Height="10" Width="100">
        <TextBlock Text="{Binding ElementName=HorizontalRowLabel, Path=TextContent}" Foreground="Black" FontSize="6" MouseDown="TextBlock_MouseDown"/>
    </Border>

Horizontal C#:

public partial class HorizontalRowLabel : UserControl
{
    public static readonly DependencyProperty TextContentProperty = DependencyProperty.Register("TextContent", typeof(string),
        typeof(HorizontalRowLabel), new FrameworkPropertyMetadata(""));
    public string TextContent
    {
        get { return (string)GetValue(TextContentProperty); }
        set { SetValue(TextContentProperty, value); }
    }

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show(TextContent);
    }

    public HorizontalRowLabel()
    {
        InitializeComponent();
    }
}

    //Adds text HorizontalRowLabel UserControl, then adds HRL to Grid.
    public void InitRowKeys(Grid puzzle)
    {
        for(int i = 0; i < HorizontalKeys.Length; i++)
        {
            RowDefinition row = new RowDefinition();
            HorizontalRowLabel hrow = new HorizontalRowLabel();

            row.Height = new GridLength(10);

            for(int j = 0; j < HorizontalKeys[i].Length; j++)
            {
                if(HorizontalKeys[i].Length == 0 || j == HorizontalKeys[i].Length - 1)
                {
                    hrow.TextContent += HorizontalKeys[i][j].ToString();
                    hrow.Foreground = Brushes.Black;
                    hrow.SetValue(Grid.RowProperty, i);
                    hrow.SetValue(Grid.ColumnProperty, 0);
                    hrow.FontSize = 6;
                    hrow.HorizontalAlignment = HorizontalAlignment.Right;
                    hrow.VerticalAlignment = VerticalAlignment.Center;

                }
                else
                {
                    hrow.TextContent += HorizontalKeys[i][j].ToString() + " ";
                    hrow.SetValue(Grid.RowProperty, i);
                    hrow.SetValue(Grid.ColumnProperty, 0);
                    hrow.FontSize = 6;
                    hrow.HorizontalAlignment = HorizontalAlignment.Right;
                    hrow.VerticalAlignment = VerticalAlignment.Center;
                }
            }
            //puzzle.Margin = new Thickness(0,50,0,0);
            hrow.Width = 100;
            hrow.Height = 30;


            puzzle.RowDefinitions.Add(row);
            puzzle.Children.Add(hrow);
        }
    }

Solution

  • A Binding like

    Text="{Binding ElementName=HorizontalRowLabel, Path=TextContent}"
    

    only works if you have assigned the x:Name attribute to the UserControl:

    <UserControl ... x:Name="HorizontalRowLabel">
        ...
    </UserControl>
    

    That is however not necessary with a RelativeSource Binding:

    Text="{Binding TextContent, RelativeSource={RelativeSource AncestorType=UserControl}}"