Question

I have a simple UserControl that I want to display in my stackpanel programmatically .

When I do, the UC does not show on the screen. If I drag a single instance from the toolbox it works fine.

The User Control is XAML is

<UserControl x:Class="MYProj.Controls.SpecialNumberOption"
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="200">
    <Viewbox>
    <Grid x:Name="LayoutRoot" Background="White" Width="200" Height="300">
        <Button x:Name="buttonMe" Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="180" Height="150" Style="{StaticResource NumberButtonStyle}" Click="buttonMe_Click"/>
        <TextBlock x:Name="subText" HorizontalAlignment="Left" Margin="10,165,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="125" Width="180" FontStyle="Italic" TextAlignment="Center"/>

    </Grid>
    </Viewbox>
</UserControl>

The Codebehind

public partial class SpecialNumberOption : UserControl
{


    public event RoutedEventHandler Click;



    public SpecialNumberOption()
    {
        InitializeComponent();


        this.applyStyle();
    }

    public SpecialNumberOption(SurveyQuestionOption option)
    {
        this.buttonMe.Content = option.Text;
        this.subText.Text = option.SubText;

        this.applyStyle();
    }


    private void applyStyle()
    {

        this.buttonMe.FontSize = 26;
        this.buttonMe.Background = standardBackground;
        this.buttonMe.Foreground = standardForecolor;

    }

    ///Raise the event to the outside

    private void buttonMe_Click(object sender, RoutedEventArgs e)
    {
        Click(this, e);
    }



}

Implementation

This is how Im adding the control

    foreach (var y in x.Options)
    {

            //Create new instance from An object
            var r = new SpecialNumberOption(y);

            // Set visibility
            r.Visibility = System.Windows.Visibility.Visible;


            r.IsEnabled = false;

            //Assign the event handler
            r.Click += r_Click;

            //This is my stackpanel
            listOptions.Children.Add(r);


            ....
    }




    //Handle the click event
    void r_Click(object sender, RoutedEventArgs e)
    {

        SpecialNumberOption o = (SpecialNumberOption)e.OriginalSource;
        ....

    }

Update

I found when I use the alternate Constructor this is when it ceases to work. I have to use the default constructor. Is this normal?

Was it helpful?

Solution

I have not checked all of your posted code for correctness but here is the issue with your constructors: you must call InitializeComponent (and it must happen before you access any named elements)

here is a version with a fix:

public SpecialNumberOption()
{
    InitializeComponent();
    this.applyStyle();
}

public SpecialNumberOption(SurveyQuestionOption option) : this () //will call the empty default constructor
{
    this.buttonMe.Content = option.Text;
    this.subText.Text = option.SubText;
}

Remark: I consider it bad style for controls to have more than the empty default constructor. The parameters should be set via a property setter. It enable you and whoever will be reusing your control to use and parameterize it in xaml.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top