--- title: "How to: Create an Add-In That Is a UI" ms.date: "03/30/2017" dev_langs: - "csharp" - "vb" helpviewer_keywords: - "creating an add-in that is a UI [WPF]" - "add-ins [WPF], UI" - "creating UI add-ins [WPF]" - "UI add-ins [WPF], creating" - "implementing UI add-ins [WPF]" - "pipeline segments [WPF], creating add-ins" ms.assetid: 86375525-282b-4039-8352-8680051a10ea --- # How to: Create an Add-In That Is a UI This example shows how to create an add-in that is a Windows Presentation Foundation (WPF) which is hosted by a WPF standalone application. The add-in is a UI that is a WPF user control. The content of the user control is a single button that, when clicked, displays a message box. The WPF standalone application hosts the add-in UI as the content of the main application window. **Prerequisites** This example highlights the WPF extensions to the .NET Framework add-in model that enable this scenario, and assumes the following: - Knowledge of the .NET Framework add-in model, including pipeline, add-in, and host development. If you are unfamiliar with these concepts, see [Add-ins and Extensibility](/previous-versions/dotnet/netframework-4.0/bb384200(v%3dvs.100)). For a tutorial that demonstrates the implementation of a pipeline, an add-in, and a host application, see [Walkthrough: Creating an Extensible Application](/previous-versions/dotnet/netframework-4.0/bb788290(v%3dvs.100)). - Knowledge of the WPF extensions to the .NET Framework add-in model. See [WPF Add-Ins Overview](wpf-add-ins-overview.md). ## Example To create an add-in that is a WPF UI requires specific code for each pipeline segment, the add-in, and the host application. ## Implementing the Contract Pipeline Segment When an add-in is a UI, the contract for the add-in must implement . In the example, `IWPFAddInContract` implements , as shown in the following code. [!code-csharp[SimpleAddInIsAUISample#ContractCode](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/Contracts/IWPFAddInContract.cs#contractcode)] [!code-vb[SimpleAddInIsAUISample#ContractCode](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/Contracts/IWPFAddInContract.vb#contractcode)] ## Implementing the Add-In View Pipeline Segment Because the add-in is implemented as a subclass of the type, the add-in view must also subclass . The following code shows the add-in view of the contract, implemented as the `WPFAddInView` class. [!code-csharp[SimpleAddInIsAUISample#AddInViewCode](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/AddInViews/WPFAddInView.cs#addinviewcode)] [!code-vb[SimpleAddInIsAUISample#AddInViewCode](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/AddInViews/WPFAddInView.vb#AddInViewCode)] Here, the add-in view is derived from . Consequently, the add-in UI should also derive from . ## Implementing the Add-In-Side Adapter Pipeline Segment While the contract is an , the add-in is a (as specified by the add-in view pipeline segment). Therefore, the must be converted to an before crossing the isolation boundary. This work is performed by the add-in-side adapter by calling , as shown in the following code. [!code-csharp[SimpleAddInIsAUISample#AddInSideAdapterCode](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/AddInSideAdapters/WPFAddIn_ViewToContractAddInSideAdapter.cs#addinsideadaptercode)] [!code-vb[SimpleAddInIsAUISample#AddInSideAdapterCode](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/AddInSideAdapters/WPFAddIn_ViewToContractAddInSideAdapter.vb#addinsideadaptercode)] In the add-in model where an add-in returns a UI (see [Create an Add-In That Returns a UI](how-to-create-an-add-in-that-returns-a-ui.md)), the add-in adapter converted the to an by calling . must also be called in this model, although you need to implement a method from which to write the code to call it. You do this by overriding and implementing the code that calls if the code that is calling is expecting an . In this case, the caller will be the host-side adapter, which is covered in a subsequent subsection. > [!NOTE] > You also need to override in this model to enable tabbing between host application UI and add-in UI. For more information, see "WPF Add-In Limitations" in [WPF Add-Ins Overview](wpf-add-ins-overview.md). Because the add-in-side adapter implements an interface that derives from , you also need to implement , although this is ignored when is overridden. ## Implementing the Host View Pipeline Segment In this model, the host application typically expects the host view to be a subclass. The host-side adapter must convert the to a after the crosses the isolation boundary. Because a method isn't being called by the host application to get the , the host view must "return" the by containing it. Consequently, the host view must derive from a subclass of that can contain other UIs, such as . The following code shows the host view of the contract, implemented as the `WPFAddInHostView` class. [!code-csharp[WPFAddInHostView class](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/HostViews/WPFAddInHostView.cs#HostViewCode)] [!code-vb[WPFAddInHostView class](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/HostViews/WPFAddInHostView.vb#HostViewCode)] ## Implementing the Host-Side Adapter Pipeline Segment While the contract is an , the host application expects a (as specified by the host view). Consequently, the must be converted to a after crossing the isolation boundary, before being set as content of the host view (which derives from ). This work is performed by the host-side adapter, as shown in the following code. [!code-csharp[Host-side adapter](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/HostSideAdapters/WPFAddIn_ContractToViewHostSideAdapter.cs#HostSideAdapterCode)] [!code-vb[Host-side adapter](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/HostSideAdapters/WPFAddIn_ContractToViewHostSideAdapter.vb#HostSideAdapterCode)] As you can see, the host-side adapter acquires the by calling the add-in-side adapter's method (this is the point where the crosses the isolation boundary). The host-side adapter then converts the to a by calling . Finally, the is set as the content of the host view. ## Implementing the Add-In With the add-in-side adapter and add-in view in place, the add-in can be implemented by deriving from the add-in view, as shown in the following code. [!code-csharp[Add-in implementation](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/WPFAddIn1/AddInUI.xaml.cs#AddInCodeBehind)] [!code-vb[Add-in implementation](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/WPFAddIn1/AddInUI.xaml.vb#AddInCodeBehind)] From this example, you can see one interesting benefit of this model: add-in developers only need to implement the add-in (since it is the UI as well), rather than both an add-in class and an add-in UI. ## Implementing the Host Application With the host-side adapter and host view created, the host application can use the .NET Framework add-in model to open the pipeline and acquire a host view of the add-in. These steps are shown in the following code. [!code-csharp[Acquiring a host view of the add-in](~/samples/snippets/csharp/VS_Snippets_Wpf/SimpleAddInIsAUISample/CSharp/Host/MainWindow.xaml.cs#GetUICode)] [!code-vb[Acquiring a host view of the add-in](~/samples/snippets/visualbasic/VS_Snippets_Wpf/SimpleAddInIsAUISample/VisualBasic/Host/MainWindow.xaml.vb#GetUICode)] The host application uses typical .NET Framework add-in model code to activate the add-in, which implicitly returns the host view to the host application. The host application subsequently displays the host view (which is a ) from a . The code for processing interactions with the add-in UI runs in the add-in's application domain. These interactions include the following: - Handling the event. - Showing the . This activity is completely isolated from the host application. ## See also - [Add-ins and Extensibility](/previous-versions/dotnet/netframework-4.0/bb384200(v%3dvs.100)) - [WPF Add-Ins Overview](wpf-add-ins-overview.md)