1

I have my custom control MyControl, which has a public method Start().

public partial class MyControl : UserControl
{
    // This must be private.
    private int _idNumber;

    public MyControl()
    {
        InitializeComponent();
    }

    public void Start(int idNumber)
    {
        _idNumber = idNumber;
    }
}

In the MainWindow, I put one MyControl with x:Name="myControl".

<Window x:Class="MyNameSpace.MainWindow"
        xmlns:local="clr-namespace:MyNameSpace">
    <Grid>
        <local:MyControl x:Name="myControl"/>
    </Grid>
</Window>

In the Start method of the MainWindow, I call the Start method of MyControl using x:Name.

public partial class MainWindow : Window
{
    // This must be private
    private int _myContolId;

    public MainWindow()
    {
        InitializeComponent();
    }

    public void Start()
    {
        // ID must be set here.
        _myControlId = 1;
        myControl.Start(_myControlId);
    }
}

How can I do the same thing without using x:Name?

Note that Loaded event of MyControl is ineffective in my case, since the Start() method of MyControl MUST be called before it is loaded as a visual element.

It is also ineffective to call Start in the constructor of MyControl or when it is initialized, since the int argument idNumber must be set in the Start method of MainWindow.

What is more, both _idNumber of MyControl and _myContolId of MainWindow must be private, for both setter and getter.

user4134476
  • 385
  • 4
  • 22
  • 1
    Call Start in the constructor of MyControl? Or in an overridden OnInitialized method? – Clemens Oct 04 '15 at 08:21
  • @Clemens Thank you for your quick reply but this is impossible. I explained what I really want to do in the edited version of my question. – user4134476 Oct 04 '15 at 08:49

1 Answers1

1

Handle Initialized event of your UserControl. <local:MyControl x:Name="myControl" Initialized="myControl_Initialized"/>

Whether you choose to handle Loaded or Initialized depends on your requirements. If you do not need to read element properties, intend to reset properties, and do not need any layout information, Initialized might be the better event to act upon. If you need all properties of the element to be available, and you will be setting properties that are likely to reset the layout, Loaded might be the better event to act upon.

Source : FrameworkElement.Initialized Event

You should create the UserControl in code like below and add it :

 public partial class MainWindow : Window
 {
// This must be private
private int _myContolId;

public MainWindow()
{
    InitializeComponent();
}

public void Start()
{
    // ID must be set here.
    _myControlId = 1;
    MyControl myControl = new MyControl();
    myControl.Start(_myControlId);

    GridContainer.Children.Add(myControl);
}

}

This will solve your problem. If you declare an element/control XAML, then it will be created as XAML file is parsed.

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
  • Thank you for your reply but this is impossible. I explained what I really want to do in the edited version of my question. – user4134476 Oct 04 '15 at 08:43
  • Thank you but in my actual code, the XAML structure is much more complicated and it is very difficult to add an element in code-behind. – user4134476 Oct 04 '15 at 09:02
  • Use can use a Bridge (Custom class), fill it's properties from MainWindow, and then handle Initialize event of your UserControl and get these properties etc from Bridge object. This bridge class can be declared as Application/Window resource, so it will be available to both MainWindow and UserControl. – AnjumSKhan Oct 04 '15 at 09:44
  • Thank you very much for your answer. This will realize what I wanted. – user4134476 Oct 04 '15 at 10:21
  • @user4134476 why did you say it is impossible? handling the `Initialized` event seems OK. It occurs before `Loaded`, don't you mean `Start` should also be called ***before*** the control is initialized, do you? that's impossible. – Hopeless Oct 04 '15 at 10:22