Create a Custom Tab - ribbon

When I start a new Excel Web Add-in, by default the blank project has a MyAppName.xml file that declares the ribbon.
The declaration sets a custom group and a custom control under the native Home Excel tab.
What I want is to create a separate tab for my Addin.
In the file project itself, there are these code lines:
<!-- Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab. -->
<OfficeTab id="TabHome">
So I changed OfficeTab for CustomTab, but now I get the message in the error list:
The element 'CustomTab' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides' has incomplete content. List of possible elements expected: 'Group, Label' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides'.
Do you know how I can create a custom tab? What am I doing wrong?
I'm using:
Microsoft Visual Studio Enterprise 2017
Version 15.2 (26430.12) Release
VisualStudio.15.Release/15.2.0+26430.12
Thanks.

Below is an example manifest that uses CustomTab. Can you compare your's with the example and see what might be different? Are you giving the CustomTab a unique ID? Does it have Group and Label child elements?
<?xml version="1.0" encoding="utf-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<!-- See https://github.com/OfficeDev/Office-Add-in-Commands-Samples for documentation-->
<!-- BeginBasicSettings: Add-in metadata, used for all versions of Office unless override provided -->
<!--IMPORTANT! Id must be unique for your add-in. If you copy this manifest ensure that you change this id to your own GUID. -->
<Id>e504fb41-a92a-4526-b101-542f357b7acb</Id>
<Version>1.0.0.0</Version>
<ProviderName>Contoso</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<!-- The display name of your add-in. Used on the store and various placed of the Office UI such as the add-ins dialog -->
<DisplayName DefaultValue="Add-in Commands Sample" />
<Description DefaultValue="Sample that illustrates add-in commands basic control types and actions" />
<!--Icon for your add-in. Used on installation screens and the add-ins dialog -->
<IconUrl DefaultValue="https://contoso.com/assets/icon-32.png" />
<HighResolutionIconUrl DefaultValue="https://contoso.com/assets/hi-res-icon.png" />
<SupportUrl DefaultValue="[Insert the URL of a page that provides support information for the app]" />
<!--BeginTaskpaneMode integration. Office 2013 and any client that doesn't understand commands will use this section.
This section will also be used if there are no VersionOverrides -->
<Hosts>
<Host Name="Document"/>
</Hosts>
<DefaultSettings>
<SourceLocation DefaultValue="https://commandsimple.azurewebsites.net/Taskpane.html" />
</DefaultSettings>
<!--EndTaskpaneMode integration -->
<Permissions>ReadWriteDocument</Permissions>
<!--BeginAddinCommandsMode integration-->
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
<Hosts>
<!--Each host can have a different set of commands. Cool huh!? -->
<!-- Workbook=Excel Document=Word Presentation=PowerPoint -->
<!-- Make sure the hosts you override match the hosts declared in the top section of the manifest -->
<Host xsi:type="Document">
<!-- Form factor. Currently only DesktopFormFactor is supported. We will add TabletFormFactor and PhoneFormFactor in the future-->
<DesktopFormFactor>
<!--Function file is an html page that includes the javascript where functions for ExecuteAction will be called.
Think of the FunctionFile as the "code behind" ExecuteFunction-->
<FunctionFile resid="Contoso.FunctionFile.Url" />
<!--PrimaryCommandSurface==Main Office app ribbon-->
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<!--Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab -->
<!-- Documentation includes all the IDs currently tested to work -->
<CustomTab id="Contoso.Tab1">
<!--Group ID-->
<Group id="Contoso.Tab1.Group1">
<!--Label for your group. resid must point to a ShortString resource -->
<Label resid="Contoso.Tab1.GroupLabel" />
<Icon>
<!-- Sample Todo: Each size needs its own icon resource or it will look distorted when resized -->
<!--Icons. Required sizes: 16, 32, 80; optional: 20, 24, 40, 48, 64. You should provide as many sizes as possible for a great user experience. -->
<!--Use PNG icons and remember that all URLs on the resources section must use HTTPS -->
<bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
<bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
<bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
</Icon>
<!--Control. It can be of type "Button" or "Menu" -->
<Control xsi:type="Button" id="Contoso.FunctionButton">
<!--Label for your button. resid must point to a ShortString resource -->
<Label resid="Contoso.FunctionButton.Label" />
<Supertip>
<!--ToolTip title. resid must point to a ShortString resource -->
<Title resid="Contoso.FunctionButton.Label" />
<!--ToolTip description. resid must point to a LongString resource -->
<Description resid="Contoso.FunctionButton.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.FunctionButton.Icon16" />
<bt:Image size="32" resid="Contoso.FunctionButton.Icon32" />
<bt:Image size="80" resid="Contoso.FunctionButton.Icon80" />
</Icon>
<!--This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFunction or ShowTaskpane-->
<!--Look at the FunctionFile.html page for reference on how to implement the function -->
<Action xsi:type="ExecuteFunction">
<!--Name of the function to call. This function needs to exist in the global DOM namespace of the function file-->
<FunctionName>writeText</FunctionName>
</Action>
</Control>
<Control xsi:type="Button" id="Contoso.TaskpaneButton">
<Label resid="Contoso.TaskpaneButton.Label" />
<Supertip>
<Title resid="Contoso.TaskpaneButton.Label" />
<Description resid="Contoso.TaskpaneButton.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
<bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
<bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>Button2Id1</TaskpaneId>
<!--Provide a url resource id for the location that will be displayed on the task pane -->
<SourceLocation resid="Contoso.Taskpane1.Url" />
</Action>
</Control>
<!-- Menu example -->
<Control xsi:type="Menu" id="Contoso.Menu">
<Label resid="Contoso.Dropdown.Label" />
<Supertip>
<Title resid="Contoso.Dropdown.Label" />
<Description resid="Contoso.Dropdown.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
<bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
<bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
</Icon>
<Items>
<Item id="Contoso.Menu.Item1">
<Label resid="Contoso.Item1.Label"/>
<Supertip>
<Title resid="Contoso.Item1.Label" />
<Description resid="Contoso.Item1.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
<bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
<bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>MyTaskPaneID1</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane1.Url" />
</Action>
</Item>
<Item id="Contoso.Menu.Item2">
<Label resid="Contoso.Item2.Label"/>
<Supertip>
<Title resid="Contoso.Item2.Label" />
<Description resid="Contoso.Item2.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
<bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
<bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>MyTaskPaneID2</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane2.Url" />
</Action>
</Item>
</Items>
</Control>
</Group>
<!-- Label of your tab -->
<!-- If validating with XSD it needs to be at the end -->
<Label resid="Contoso.Tab1.TabLabel" />
</CustomTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
</Hosts>
<Resources>
<bt:Images>
<bt:Image id="Contoso.TaskpaneButton.Icon16" DefaultValue="https://myCDN/Images/Button16x16.png" />
<bt:Image id="Contoso.TaskpaneButton.Icon32" DefaultValue="https://myCDN/Images/Button32x32.png" />
<bt:Image id="Contoso.TaskpaneButton.Icon80" DefaultValue="https://myCDN/Images/Button80x80.png" />
<bt:Image id="Contoso.FunctionButton.Icon" DefaultValue="https://myCDN/Images/ButtonFunction.png" />
</bt:Images>
<bt:Urls>
<bt:Url id="Contoso.FunctionFile.Url" DefaultValue="https://commandsimple.azurewebsites.net/FunctionFile.html" />
<bt:Url id="Contoso.Taskpane1.Url" DefaultValue="https://commandsimple.azurewebsites.net/Taskpane.html" />
<bt:Url id="Contoso.Taskpane2.Url" DefaultValue="https://commandsimple.azurewebsites.net/Taskpane2.html" />
</bt:Urls>
<bt:ShortStrings>
<bt:String id="Contoso.FunctionButton.Label" DefaultValue="Execute Function" />
<bt:String id="Contoso.TaskpaneButton.Label" DefaultValue="Show Taskpane" />
<bt:String id="Contoso.Dropdown.Label" DefaultValue="Dropdown" />
<bt:String id="Contoso.Item1.Label" DefaultValue="Show Taskpane 1" />
<bt:String id="Contoso.Item2.Label" DefaultValue="Show Taskpane 2" />
<bt:String id="Contoso.Tab1.GroupLabel" DefaultValue="Test Group" />
<bt:String id="Contoso.Tab1.TabLabel" DefaultValue="Test Tab" />
</bt:ShortStrings>
<bt:LongStrings>
<bt:String id="Contoso.FunctionButton.Tooltip" DefaultValue="Click to Execute Function" />
<bt:String id="Contoso.TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane" />
<bt:String id="Contoso.Dropdown.Tooltip" DefaultValue="Click to Show Options on this Menu" />
<bt:String id="Contoso.Item1.Tooltip" DefaultValue="Click to Show Taskpane1" />
<bt:String id="Contoso.Item2.Tooltip" DefaultValue="Click to Show Taskpane2" />
</bt:LongStrings>
</Resources>
</VersionOverrides>
</OfficeApp>
See also this article and the samples it links to. And check out Validate and Troubleshoot your Manifest too.

Related

Linker preventing MvvmCross MvxApplication Initialize being called

I have updated my Target Android Api to Android 12 (API 31) so our app can be accepted in the PlayStore. This meant that the Android X packages had to be updated as well.
However, our MvxApplication Intialize override is no longer called, meaning we can not call RegisterCustomAppStart, so the app gets stuck on the splash screen.
This only happens when Linker (Link SDK assemblies only) is enabled. When it is disabled, everything works fine.
I find it impossible to determine what is happening under the hood with MvvmCross startup process, and therefore determine what may be linked out. I have included as many classes and methods as I can think of in our "LinkerPleaseInclude" file, but that is really stabbing in the dark.
ADB will output the missing method at runtime. It is indeed stabbing in the dark. It's more of a Xamarin issue than an MvvmCross issue.
The Custom Linker Configuration is a superior alternative to LinkerPleaseInclude.cs. I use this XML to prevent linking out key MvvmCross bits with an Android MvvmCross 8.x app:
<assembly fullname="MvvmCross">
<type fullname="MvvmCross.IoC.MvxPropertyInjector" />
<type fullname="MvvmCross.Core.MvxSettings" />
<type fullname="MvvmCross.Core.MvxStringToTypeParser" />
<type fullname="MvvmCross.ViewModels.MvxViewModelLoader" />
<type fullname="MvvmCross.Platforms.Android.Views.MvxSavedStateConverter" />
<type fullname="MvvmCross.ViewModels.MvxAppStart`1" />
</assembly>
Here is a full example from an Android app built with MvvmCross 8.0.2. The idea is to keep only what is needed. For example, remove the NumberPicker parts if you don't use that widget in your app.
<?xml version="1.0" encoding="utf-8" ?>
<!--
This file prevents the Xamarin.Android Linker from removing code from the final executable.
C# Properties are implemented as two methods: get_PropertyName + put_PropertyName
C# Events are implemented as two methods: add_EventName + remove_EventName
C# Constructors are implemented as such:
default: .ctor
string parameter: System.Void .ctor(System.String)
See https://docs.microsoft.com/en-us/xamarin/cross-platform/deploy-test/linker for more information.
-->
<linker>
<!-- Mono.Android -->
<assembly fullname="Mono.Android">
<type fullname="Android.Views.View">
<method name="get_Text" />
<method name="put_Text" />
<method name="get_ContentDescription" />
<method name="put_ContentDescription" />
<method name="add_Click" />
<method name="remove_Click" />
<method name="add_LongClick" />
<method name="remove_LongClick" />
<method name="Invalidate" />
</type>
<type fullname="Android.Views.View.LongClickEventArgs">
<method name="System.Void .ctor(System.Boolean)" />
<method name="get_Handled" />
<method name="put_Handled" />
</type>
<type fullname="Android.Widget.TextView">
<method name="add_AfterTextChanged" />
<method name="remove_AfterTextChanged" />
</type>
<type fullname="Android.Widget.NumberPicker">
<method name="get_Value" />
<method name="put_Value" />
<method name="add_ValueChanged" />
<method name="remove_ValueChanged" />
</type>
<type fullname="Android.Widget.NumberPicker.ValueChangeEventArgs">
<method name="get_Picker" />
<method name="put_Picker" />
<method name="get_OldVal" />
<method name="put_OldVal" />
<method name="get_NewVal" />
<method name="put_NewVal" />
</type>
</assembly>
<!-- netstandard -->
<assembly fullname="netstandard">
<type fullname="System.TimeSpan" >
<method name="get_Hours" />
<method name="get_Minutes" />
<method name="get_Seconds" />
</type>
</assembly>
<!-- Google Material Design Components -->
<assembly fullname="Xamarin.Google.Android.Material">
<type fullname="Google.Android.Material.TextField.TextInputLayout">
<method name="get_Hint" />
<method name="set_Hint" />
<method name="get_Error" />
<method name="set_Error" />
</type>
<type fullname="Google.Android.Material.TextField.TextInputEditText">
<method name="get_Text" />
<method name="set_Text" />
</type>
</assembly>
<!-- MvvmCross -->
<assembly fullname="MvvmCross">
<type fullname="MvvmCross.IoC.MvxPropertyInjector" />
<type fullname="MvvmCross.Core.MvxSettings" />
<type fullname="MvvmCross.Core.MvxStringToTypeParser" />
<type fullname="MvvmCross.ViewModels.MvxViewModelLoader" />
<type fullname="MvvmCross.Platforms.Android.Views.MvxSavedStateConverter" />
<type fullname="MvvmCross.ViewModels.MvxAppStart`1" />
</assembly>
<!-- Xamarin.AndroidX.Core -->
<assembly fullname="Xamarin.AndroidX.Core">
<type fullname="AndroidX.Core.App.CoreComponentFactory" />
</assembly>
</linker>

Localizing claims in custom policy

I have custom claims in my sign-up page register_header and password_header and I want to localize them to Japanese.
Here is my custom policy:
Claims
<ClaimType Id="register_heading">
<DataType>string</DataType>
<AdminHelpText>A claim responsible for holding response messages to send to the relying party</AdminHelpText>
<UserHelpText>A claim responsible for holding response messages to send to the relying party</UserHelpText>
<UserInputType>Paragraph</UserInputType>
</ClaimType>
<ClaimType Id="password_header">
<DataType>string</DataType>
<AdminHelpText>A claim responsible for holding response messages to send to the relying party</AdminHelpText>
<UserHelpText>A claim responsible for holding response messages to send to the relying party</UserHelpText>
<UserInputType>Paragraph</UserInputType>
</ClaimType>
Technical Profile
<TechnicalProfile Id="LocalAccountSignUpWithreadOnlyEmail">
<DisplayName>Email signup</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="IpAddressClaimReferenceId">IpAddress</Item>
<Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
<Item Key="language.button_continue">Continue</Item>
<Item Key="setting.showCancelButton">false</Item>
<!-- Sample: Remove sign-up email verification -->
<Item Key="EnforceEmailVerification">False</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
<InputClaim ClaimTypeReferenceId="readOnlyEmail" />
<InputClaim ClaimTypeReferenceId="givenName" />
<InputClaim ClaimTypeReferenceId="surName" />
<!-- claims needed for localization -->
<InputClaim ClaimTypeReferenceId="register_header" DefaultValue="Register account" />
<InputClaim ClaimTypeReferenceId="password_header" DefaultValue="Register password" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId" />
<!-- Sample: Display the readOnlyEmail claim type (instead of email claim type)-->
<OutputClaim ClaimTypeReferenceId="readOnlyEmail" Required="true" />
<OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
<OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
<OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" />
<OutputClaim ClaimTypeReferenceId="newUser" />
<!-- Optional claims, to be collected from the user -->
<OutputClaim ClaimTypeReferenceId="givenName" Required="true" />
<OutputClaim ClaimTypeReferenceId="surName" Required="true" />
<OutputClaim ClaimTypeReferenceId="TnC" Required="true" />
<!-- claims for localization -->
<OutputClaim ClaimTypeReferenceId="register_header" />
<OutputClaim ClaimTypeReferenceId="password_header" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
</ValidationTechnicalProfiles>
<!-- Sample: Disable session management for sign-up page -->
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
Content Definition
<ContentDefinition Id="api.localaccountsignup">
<LoadUri>Insert URL here</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:1.2.0</DataUri>
<LocalizedResourcesReferences MergeBehavior="ReplaceAll">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.localaccountsignup.en" />
<LocalizedResourcesReference Language="ja" LocalizedResourcesReferenceId="api.localaccountsignup.ja" />
</LocalizedResourcesReferences>
Localized Resources
<LocalizedResources Id="api.localaccountsignup.ja">
<LocalizedStrings>
<LocalizedString ElementType="ClaimType" ElementId="register_header" StringId="DisplayName">アカウントを登録</LocalizedString>
<LocalizedString ElementType="ClaimType" ElementId="password_header" StringId="DisplayName">パスワードを登録</LocalizedString>
</LocalizedStrings>
My problem is the Japanese translation are returned as <label> in the HTML.
But their English counterpart is returned as <p> with the id attribute
I want to use the id but it is only available to the English translation.
Is there a way for the custom policy to change the text in <p> to Japanese and keep the id instead of creating a <label> element? If possible I don't want to use Javascript.
• I would suggest you to please try configuring the localization string ids in the custom policy regarding the two custom claims that you want to be translated in Japanese. Since you have already done the same as posted in your localization strings claims, I would suggest you to please modify your custom policy to also include the details below in it: -
<Localization Enabled="true">
<SupportedLanguages DefaultLanguage="en" MergeBehavior="ReplaceAll">
<SupportedLanguage>en</SupportedLanguage>
<SupportedLanguage>jp</SupportedLanguage>
</SupportedLanguages>
<LocalizedResources Id="api.localaccountsignup.en">
<LocalizedCollections>
<LocalizedCollection ElementType="ClaimType" ElementId="register_header" TargetCollection="Restriction">
<Item Text="StringId" Value="DisplayName" />
</LocalizedCollection>
<LocalizedCollection ElementType="ClaimType" ElementId="password_header" TargetCollection="Restriction">
<Item Text=”StringId” Value=”DisplayName”>
</LocalizedCollection>
</LocalizedCollections>
</LocalizedResources>
<LocalizedResources Id="api.localaccountsignup.jp">
<LocalizedCollections>
<LocalizedCollection ElementType="ClaimType" ElementId="<register_header in japanese" TargetCollection="Restriction">
<Item Text="StringId" Value="DisplayName" />
</LocalizedCollection>
<LocalizedCollection ElementType="ClaimType" ElementId="password_header in japanese" TargetCollection="Restriction">
<Item Text=”StringId” Value=”DisplayName”>
</LocalizedCollection>
</LocalizedCollections>
</LocalizedResources>
</Localization>
Might be when you edit your custom policy to include the display results as above, then you might be able to resolve the issue as desired. Also, do refer to the link below for more details about editing the custom policy as above.
Localised message for RestAPI error response in B2C custom policy

HTML template in xml - what kind of architecture is this?

My project has many xml files which are using to build html page & page operations. Here is the sample of grid template.
<Contact singular="Contact" indeal="" nodeal="ContactsPlaybook" tooltip="Document Playbook" library="true" tabHidden="true">
<ListingScreen handle = "PlaybookContacts.ashx" suppressCount="true" showFilters="true">
<IncludeScript src="scripts/jjedsEmaUser.js"/>
<SmartIcon editMode="false" requiredAction="Create" name="new" image="new.png" tooltip="Create" separator="false" href="PlaybookContactDetail.ashx?DealRef=${DealRef}" edit="true" />
<SmartIcon editMode="false" requiredAction="Delete" name="BulkDelete" image="delete.png" tooltip="Delete" separator="true"/>
<SmartIcon editMode="false" requiredAction="Read" actionOn="Contact" name="email" image="mail.png" tooltip="Email Team" href="PlaybookEmailTeam.ashx?DealRef=${DealRef}&Subject=Playbook&Body=${LinkToPage}" edit="true" />
<SmartIcon editMode="false" requiredAction="Read" name="print" image="print.png" tooltip="Print" onclick="javascript:window.print()" />
<!--<SmartIcon editMode="false" requiredAction="Administrate" name="CreateEmaUser" image="add_EMA_user.png" tooltip="Create EMA user" onclick="return emans.jjedsEmaUser.create('${DealRef}', '#ListingForm')" />-->
<Filters>
<Filter label="Functional Team" filter="FunctionalCategoryFilter" field="ContactGroupID" prefix="C" empty="FunctionalCategoryRef_NULL">
<PossibleValues displayProperty="Name" />
</Filter>
<Filter label="Country" filter="CountryFilter" by="name" prefix="AD" field="CountryID" displayProperty="Code" empty="-1">
</Filter>
<Filter label="Business Unit" filter="PickListIntFilter" field="BusinessUnit" prefix="C" empty="-1" onlyifsettingtrue="UseSpecialUserDealAccess">
<PossibleValues category="Deal" subcategory="BusinessUnit" />
</Filter>
</Filters>
<Sorting>
<SortColumn name="FullName" dir="asc"/>
</Sorting>
<Query alias="C" ignoreArchiving="true" ignoreDeal="true">
<Block by="C.ContactGroupID" resolveto="DepartmentName" as="Department" />
<JoinTo table="Address" alias="AD" from="C.AddressID" to="AD.AddressID">
</JoinTo>
<Constraint left="C.IsArchived" int="0" />
</Query>
<Column command="true" title="<input type='checkbox' header='true' onclick='ToggleCheckAll(this);'>" editMode="false" special="IsDelete" macro="Checkbox" onClick="ToggleCheckBox(this);"/>
<Column command="true" requiredAction="Update" title="" field="Blank" dbColumn="C.ContactID" macro="ImageLink" fieldType="Contact" tooltip="Edit" image="edit.png" edit="true" />
<Column title="Full Name" field="FullName" macro="LinkToRef" resolveto="FullContactName" from="C.ContactID" contactAlias="C" linkPage="PlaybookContactDetail.ashx"/>
<Column title="Organization" field="C.Affiliation" macro="Text" />
<Column title="Business Unit" field="C.BusinessUnit" property="BusinessUnit" macro="PickList" category="Deal" subcategory="BusinessUnit" storeInt="true" onlyifsettingtrue="UseSpecialUserDealAccess"/>
<Column title="Role" field="C.Role" macro="Text" />
<Column title="Phone" field="C.Phone" macro="Text" />
<Column title="Email" field="C.Email" macro="MailToRef" />
<DeleteDialog name="ContactDelete" info="If you really want to delete {0} please choose the contact which will be used instead."
title="Confirm delete" type="ContactDeleteDialog" >
</DeleteDialog>
</ListingScreen>
</Contact>
Can anyone tell me what kind of architecture is this and what is the real benefit of using this architecture?
It is used in Single page applications to populate the page using an ajax call from the browser to XML files/JSON files in the server thus avoiding reloading of the entire page.
Look into this example
https://www.w3schools.com/js/tryit.asp?filename=tryjs_ajax_xml2
Here on clicking the button the table gets loaded with the xml data from cd_catalog.xml
https://www.w3schools.com/js/cd_catalog.xml
Its architechture is similar to HTML in the way that both are markup languages.
The data is accessed using the nested structure of the tags.In the cd.catalog example the title column is accessed as catalog->cd->title.

Office AddIn button's icon won't show up

Here's extract from the manifest's Host
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<CustomTab id="MyTab">
<Group id="Raporty.GroupPabcd">
<Label resid="Raporty.GroupPabcd.Label" />
<Icon>
<bt:Image resid="Raporty.Icon1_16" size="16" />
<bt:Image resid="Raporty.Icon1_20" size="20" />
<bt:Image resid="Raporty.Icon1_24" size="24" />
<bt:Image resid="Raporty.Icon1_32" size="32" />
<bt:Image resid="Raporty.Icon1_40" size="40" />
<bt:Image resid="Raporty.Icon1_48" size="48" />
<bt:Image resid="Raporty.Icon1_64" size="64" />
<bt:Image resid="Raporty.Icon1_80" size="80" />
</Icon>
<Control xsi:type="Button" id="RaportPabcd.Button">
<Label resid="RaportPabcd.Button.Label" />
<Supertip>
<Title resid="RaportPabcd.Button.Label" />
<Description resid="RaportPabcd.Button.Tooltip" />
</Supertip>
<Icon>
<bt:Image resid="Raporty.Icon1_16" size="16" />
<bt:Image resid="Raporty.Icon1_20" size="20" />
<bt:Image resid="Raporty.Icon1_24" size="24" />
<bt:Image resid="Raporty.Icon1_32" size="32" />
<bt:Image resid="Raporty.Icon1_40" size="40" />
<bt:Image resid="Raporty.Icon1_48" size="48" />
<bt:Image resid="Raporty.Icon1_64" size="64" />
<bt:Image resid="Raporty.Icon1_80" size="80" />
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>ButtonId1</TaskpaneId>
<SourceLocation resid="Contoso.Taskpane.Url" />
</Action>
</Control>
</Group>
<Label resid="Raporty.Tab.Label" />
</CustomTab>
</ExtensionPoint>
as well as the resources
<Resources>
<bt:Images>
<bt:Image id="Raporty.Icon1_16" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_16.png" />
<bt:Image id="Raporty.Icon1_20" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_20.png" />
<bt:Image id="Raporty.Icon1_24" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_24.png" />
<bt:Image id="Raporty.Icon1_32" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_32.png" />
<bt:Image id="Raporty.Icon1_40" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_40.png" />
<bt:Image id="Raporty.Icon1_48" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_48.png" />
<bt:Image id="Raporty.Icon1_64" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_64.png" />
<bt:Image id="Raporty.Icon1_80" DefaultValue="~remoteAppUrl/Images/ReportIcons/report_1_80.png" />
</bt:Images>
</Resources>
Problem is that the button shows the default icon
I tried to access the image directly in the browser (i.e. http://localhost/ExcelWebWeb/Images/ReportIcons/report_1_32.png) and it does show up
I have taken a look at the IIS logs to see if the image was even queried by the Excel app, but it wasn't. I can only see access logs from my local browser to the icons while the addin only queries the html/js files (for the TaskPane) without querying for the button's image.
I had the same issue but found a solution. Please add the following to the manifest.xml file:
<Version>1.0.0.0</Version>
<ProviderName>abc</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<!-- The display name of your add-in. Used on the store and various places of
the Office UI such as the add-ins dialog. -->
<DisplayName DefaultValue="abc" />
<IconUrl DefaultValue="~remoteAppUrl/Images/add-in-icon-lo-res.png"/>
<HighResolutionIconUrl DefaultValue="~remoteAppUrl/Images/add-in-icon-hi-res.png"/>
Resolution for the image should be Iconurls 64 x 64 pixels with 8 bit depth in png and for HighResolutionIconUrl 128 x 128 pixels
try replacing '~remoteAppUrl' with localhost:[port number]. When you publish the app, this needs to be changed to the host and port number
<CustomTab id="MyTab">
<Group id="Raporty.MyTab.GroupPabcd">
<Label resid="Raporty.MyTab.GroupPabcd.Label" />
......
<Label resid="Raporty.MyTab.TabLabel" />
That is corect code for manifest.

Update app.config from WIX setup?

I am trying Wix 3.6 and this is how it looks right now :
<?xml version="1.0" encoding="UTF-8"?>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="myappINSTALLDIR" Name="myapp5Service">
<Component Id="SampleServiceComponent" DiskId="1" Guid="6f51c0f3-776c-4aec-a200-1f199352c6c3" Win64="yes">
<File Id="myapp5.WindowsService.exe" Name="myapp5.WindowsService.exe" Source="$(var.myapp.WindowsService.TargetDir)\myapp5.WindowsService.exe" KeyPath='yes'/>
...
<ServiceInstall Id="InstallmyappService" DisplayName="myappService" Name="myapp5.WindowsService.exe" Description="myapp 5 Service - För effektivare och enklare operationsplanering" Account="LocalSystem" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" />
<ServiceControl Id="ControlmyappService" Name="myapp5.WindowsService.exe" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
</Directory>
</Directory>
<WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Image\myappTopBanner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Image\myappDialogBackground.bmp" />
<Property Id="WIXUI_INSTALLDIR" Value="myappINSTALLDIR" />
<UIRef Id="WixUI_InstallDir" />
<Feature Id="ProductFeature" Title="Wix_myapp.WindowsService" Level="1">
<ComponentRef Id="SampleServiceComponent" />
</Feature>
<Media Id="1" Cabinet="SampleServiceComponent.cab" EmbedCab="yes" />
</Product>
Now I need to add a dialog to the Wix setup where one appSetting and one baseadress(WCF) is set to the app.config. This most be done before the installation becouse it will decide the name of the Windows Service that the Wix is installning.
And exampel would be great!
Edit 1:
<WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Image\myappTopBanner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Image\myappDialogBackground.bmp" />
<Property Id="SERVICEADDRESS" Value="http://serviceaddress"/>
<Property Id="WIXUI_INSTALLDIR" Value="myappINSTALLDIR" />
<UIRef Id="WixUI_InstallDir" />
<util:XmlFile Id="UpdateBaseAddress"
Action="setValue"
File="$(var.myapp.WindowsService.TargetDir)\myapp5.WindowsService.exe.config"
SelectionLanguage="XPath"
Permanent="yes"
ElementPath="/configuration/applicationSettings/ServiceName"
Name="baseAddress" Value="[SERVICEADDRESS]" />
<Feature Id="ProductFeature" Title="Wix_myapp.WindowsService" Level="1">
<ComponentRef Id="SampleServiceComponent" />
</Feature>
<Media Id="1" Cabinet="SampleServiceComponent.cab" EmbedCab="yes" />
</Product>
You could add in a reference to the WixUtilExtension.dll to the installer project, then use XmlFile to update the app.config like:
<Property Id="SERVICEADDRESS" Value="http://serviceaddress"/>
<util:XmlFile Id="UpdateBaseAddress"
Action="setValue"
File="[DirApplication]$(var.app.config)"
SelectionLanguage="XPath"
Permanent="yes"
ElementPath="/configuration/applicationSettings/...."
Name="baseAddress" Value="[SERVICEADDRESS]" />
Note that you'll need to set the directory and the name of the .config file (you could just use $(var.ProjectName.TargetFileName).config which should work it out for you automatically