Взаимодействие Wix с условиями, свойствами и настраиваемыми действиями

У меня проблема с настройкой включенного состояния кнопки в диалоговом окне. Рассматриваемая кнопка определяется как:

<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Condition Action="disable">Validated = 0</Condition>
<Condition Action="enable"><![CDATA[Validated <> 0]]></Condition>
<Publish Event="EndDialog" Value="Return">1</Publish>
</Control>

Свойство Validated начинается с начального значения 0, и, как и ожидалось, следующая кнопка запускается отключенной.

<Property Id="Validated" Value="0"/>

Само свойство изменяется с помощью настраиваемого действия на другой кнопке.

<Control Id="PerformValidation" Type="PushButton" X="225" Y="75" Width="50" Height="20" Text="Validate">
<Publish Event="DoAction" Value="ValidateDB">1</Publish>
</Control>

С урезанной версией настраиваемого действия, например:

[CustomAction]
public static ActionResult ValidateDatabase(Session session)
{
session.Log("Begin ValidateDatabase");
session["Validated"] = "1";
return ActionResult.Success;
}

Проблема, с которой я сталкиваюсь, заключается в том, что кнопка «Далее» не включается повторно после запуска настраиваемого действия. Я могу подтвердить, что центр сертификации работает и свойство успешно установлено. Пользовательский интерфейс обновится, если я выполню какое-либо другое действие, вызывающее его обновление, например вернитесь на страницу назад, затем снова перейдите на эту страницу, и кнопка «Далее» станет активной.

Есть идеи, как обновить состояние кнопок после настраиваемого действия?


person BBoy    schedule 22.11.2010    source источник


Ответы (2)


http://www.mail-archive.com/[email protected]/msg05097.html предлагает решение для повторной публикации свойств, которые были изменены в настраиваемом действии, сразу после него.

Вот пример того, как я заставил это работать в моем коде:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <Binary Id="ConnectionStringExtension.dll" SourceFile="$(var.ConnectionStringExtension.TargetDir)$(var.ConnectionStringExtension.TargetName).CA.dll" />
        <CustomAction Id="MyCustomAction" BinaryKey="ConnectionStringExtension.dll" DllEntry="VerifyConnectionString" Execute="immediate"  />

        <UI>
            <Dialog Id="ConnectionStringDlg" Width="370" Height="270" Title="Database Settings - [ProductName]" NoMinimize="yes">
                <Control Id="ConnectionStringLabel" Type="Text" X="45" Y="73" Width="100" Height="15" TabSkip="no" Text="&amp;Connection String:" />
                <Control Id="ConnectionStringEdit" Type="Edit" X="45" Y="95" Width="220" Height="15" Property="CONNECTION_STRING" Text="{200}" />
                <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back">
                </Control>
                <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next">
                    <Condition Action="enable"><![CDATA[CONNECTION_STRING <> "" AND CONNECTION_STRING_VALID = "1"]]></Condition>
                    <Condition Action="disable"><![CDATA[CONNECTION_STRING = "" OR CONNECTION_STRING_VALID = "0"]]></Condition>
                </Control>
                <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>Please enter database configuration</Text>
                </Control>
                <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>{\WixUI_Font_Title}Database Settings</Text>
                </Control>
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
              <Control Id="VerifyButton" Type="PushButton"  Width="56" Height="16" X="45" Y="118" Text="Verify">
                <Publish Event="DoAction" Value="MyCustomAction">1</Publish>
                <Publish Property="TEMP_VERIFIED" Value="[CONNECTION_STRING_VALID]">1</Publish>
                <Publish Property="CONNECTION_STRING_VALID" Value="[TEMP_VERIFIED]" />
              </Control>
            </Dialog>
        </UI>
    </Fragment>
</Wix>

CustomAction устанавливает значение CONNECTION_STRING_VALID либо на 1, либо на 0, в зависимости от того, допустимо оно или нет, и я определил в другом месте, что по умолчанию его значение равно 0.

<Property Id="CONNECTION_STRING_VALID" Value="0" />

Теперь, когда я нажимаю кнопку проверки, если строка действительна, включается следующая кнопка

person Daniel Powell    schedule 21.06.2011
comment
Это прекрасно сработало. На мой взгляд, это гораздо лучшее решение, чем подход двойного диалога. Однако у меня есть задержка в несколько секунд между завершением действия и активацией кнопки. Определенно не проблема, просто любопытство. - person bigfoot; 02.11.2011
comment
Прошло некоторое время с тех пор, как я его использовал, но по памяти это было довольно мгновенно для меня, может быть, что-то связано с вашим действием? - person Daniel Powell; 03.11.2011
comment
Публикация была для меня ключевым моментом (‹Publish Property = ValueToUseInConditional Value = [ValueToUseInConditional] /› - person Owen Ivory; 11.01.2019

Это известное ограничение установщика Windows. Состояние диалогового окна не изменится, пока вы не обновите его каким-либо другим способом, например, перемещаясь вперед и назад, как вы правильно заметили.

Обходной путь здесь состоит в том, чтобы иметь два идентичных диалоговых окна, DialogA и DialogB. Кнопка PerformValidation в DialogA выполнит проверку, как сейчас, и вызовет DialogB (как NewDialog). Таким же образом кнопка PerformValidation в DialogB также выполнит проверку и вызовет DialogA. Таким образом, у вас будут диалоги, которые будут загружаться каждый раз при запуске проверки, и состояние кнопки будет отображаться правильно. Пользователь ничего не заподозрит, потому что он увидит только тот же диалог. :-)

Идея более подробно описана здесь. Это называется «двойные диалоги».

Надеюсь это поможет.

person Yan Sklyarenko    schedule 22.11.2010
comment
Спасибо Ян, я воспользуюсь этой техникой. Жалко, что установщик Windows настолько ограничен. :) - person BBoy; 23.11.2010
comment
Это возможно без двойного диалога, я просто не совсем понимаю, как это работает, я пытаюсь понять это знаю, см. msiext .codeplex.com и ознакомьтесь с их установщиком CommonUiMsi.msi, у него есть экран создания БД с кнопкой проверки, которая активируется после успеха, источник есть, и они, похоже, не используют вторичный диалог, у меня есть ощущение, что это как-то связано с тем, как они публикуют свою собственность, но все еще пытаются это выяснить. - person Daniel Powell; 21.06.2011