简体   繁体   中英

Referring to a class in a custom WPF user control that will exist in the WPF project

I'm after some advice. I have created a load of WPF user controls that all have to work with a class named TcAdsClient. This class will always be used in a project that one of these user controls is used in.

In order to get a reference to the class I have setup a method called init(TcAdsClient) in each of the user controls. Then for every control used I call this method when the MainWindow loads and pass the reference to the class through.

Is there a way in which I can get a reference without having to call a method or pass it through in a constructor. In a way I want the user control to assume the class will be available as it always will be.

Hope this makes sense,

BR

Chris

Consider a dependency injection framework (Prism, MEF). You initialize the class in the bootstrapper and the framework is then responsible for injecting it whenever it appears in the constructor of your control. While you still have to add it in constructor the whole initialization process is done for you (no risk it won't be initialized when accessed).

I know moving whole solution to Prsim only because of that is bit of an overkill, but the chances are it will provide more benefit with your app architecture in other places as well. And since you already run into composition issues it may be a clue that you can benefit from this change of architecture.

I know it's very general reply, but since you are asking for advice rather then a specific implementation, I hope it still can be helpful.

An idea:

Create an interface that will hold a property for your desired class:

public interface IMyClass
{
    MyClass TheClassINeed { get; }
}

In the form where you want to put the control, implement the class.

public partial class MainWindow : Window, IMyClass
{
    public MyClass TheClassINeed { get; set; }
}

Choose an event in the control to search for a parent that implements the IMyClass and get the interface.

If you have the name of the form in the XAML you can use this:

IMyClass interfElem = null;
UIElement element = sender;
for(;;)
{
    element = VisualTreeHelper.GetParent(element) as UIElement;

    if (element == null)
        break;

    interfElem = element as IMyClass;

    if (interfElem == null)
        continue;

    break;
}

Another possibility is to create a static class with a static field that holds your class. When the form is created, you can store there your class and every custom control can look into it. Or even a Dictionary with different instances of the class with a tag that your controls can relate to.

Edit

But I think that this kind of action can lead to much bigger error prone code. To me, it is much more "natural" to include a property where the code will set the object you want to pass to the control and let the control handle if it was provided or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM