Question

I have two custom dialogs - dlg1 and dlg2. After user clicks NEXT on dlg1 another custom popup dialog with some text and OK button should be shown. After user clicks OK on this popup dlg2 should appear. I've tried a lot of things but the best of it just shows dlg2 on top of dlg1 and OK-popup.

Was it helpful?

Solution

You have to create a modal dialog which passes the user from the first dialog to the second. Actually modal dialogs are used to show a message and then return focus to the dialog in which the modal dialog was called. I don't know if you are breaking any installer rules, if you don't return focus to the calling dialog but it seems to work:

Code for dlg1:

<UI>
  <Dialog Id="dlg1" ...>
    <Control Id="firstText" Type="Text" X="10" Y="10" Width="200" Height="17" Text="First Dialog calls Modal Dialog." />
    <Control Id="PopupButton" Type="PushButton" Text="Show Popup" Height="17" Width="56" X="100" Y="243" Default="yes">
      <Publish Event="SpawnDialog" Value="PopupDlg" />
    </Control>
  </Dialog>
</UI>

Code for PopupDlg:

<UI>
  <Dialog Id="PopupDlg" ...>
    <Control Id="OkButton" Type="PushButton" Text="{\Tahoma_Bold}OK" Height="17" Width="56" X="200" Y="175">
      <Publish Event="NewDialog" Value="dlg2" />
    </Control>
  </Dialog>
</UI>

Code for dlg2:

<UI>
  <Dialog id="dlg2" ...>
    <Control Id="secondText" Type="Text" X="10" Y="10" Width="200" Height="17" Text="Now proceed." />
    <Control Id="CancelButton" Type="PushButton" Text="Cancel" Height="17" Width="56" X="180" Y="243">
      <Publish Event="EndDialog" Value="Exit" />
    </Control>
  </Dialog>
</UI>

UPDATE Implementing the solution above produces some problems. There is one workaround though, but it will render your code less readable. Let me first describe the concept behind the workaround before I post some code. Basically you are going to only have two dialogs: One which triggers the popup and the popup itself. In the popup, you do not open a new window, as described above, instead you return focus to the calling dialog. Additionally you change the state of a property. The calling dialog gets updated, based upon the property that has been set by the modal dialog.

To achieve this goal, you will have to add controls for each state in the calling dialog, one for the case the property has been set and one for the case the property has not been set.

Code for callingDialog:

<UI>
  <Dialog Id="callingDialog" ...>
    <Control Id="BeforePopup" Type="Text" X="10" Y="10" Width="200" Height="17" Text="Here is some text." Hidden="yes">
      <Condition Action="show"><![CDATA[NOT PROP_SET_BY_MODAL_DLG]]></Condition>
      <Condition Action="hide"><![CDATA[PROP_SET_BY_MODAL_DLG]]></Condition>
    </Control>
    <Control Id="AfterPopup" Type="Text" X="10" Y="10" Width="200" Height="17" Text="Popup was shown." Hidden="yes">
      <Condition Action="show"><![CDATA[PROP_SET_BY_MODAL_DLG]]></Condition>
      <Condition Action="hide"><![CDATA[NOT PROP_SET_BY_MODAL_DLG]]></Condition>
    </Control>
    <Control Id="PopupButton" Type="PushButton" Text="Show Popup" Height="17" Width="56" X="100" Y="243" Default="yes">
      <Publish Event="SpawnDialog" Value="PopupDlg" />
    </Control>
  </Dialog>
</UI>

Code for PopupDlg:

<UI>
  <Dialog Id="PopupDlg" ...>
    <Control Id="OkButton" Type="PushButton" Text="OK" Height="17" Width="56" X="200" Y="175">
      <Publish Property="PROP_SET_BY_MODAL_DLG" Value="1" Order="1">1</Publish>
      <Publish Event="EndDialog" Value="Return" Order="2">1</Publish>
    </Control>
  </Dialog>
</UI>

OTHER TIPS

Found one more solution for this. It's to use WinForms dialogs from a custom action.

When user clicks NEXT button custom action is invoked:

 <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
       <Publish Event="DoAction" Value="SomeAction">1</Publish>
 </Control>

In this custom action you can call WinForm dialog. And don't forget to set the check for the silent install mode to make sure that the dialog will not be showed during silent install:

[CustomAction]
public static ActionResult SomeAction(Session session)
{       
   if(Int32.Parse(session["UILevel"]) > 3)
   {   
      var result = MessageBox.Show("Do something?", "Popup dialog", MessageBoxButtons.YesNo);
      session["SOMEPROP"] = result == DialogResult.Yes ? "True" : "False";
   }

   return ActionResult.Success;       
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top