2013-11-10 6 views
4

В настоящее время я анализирую XAML, который использует стиль, который широко использует MultiDataTriggers (8 триггеров данных по каждому стилю с 4-6 условиями на триггер). Рассматривая это, я рассматриваю, было бы более эффективным использовать converter (или multi value converter), тем более, что MultiDataTriggers нельзя отлаживать.Эффективность (многократного) MultiDataTrigger против конвертера

Может ли кто-нибудь авторитетно изложить, как скомпилированы MultiDataTriggers? Я понимаю, что вместе с ним собраны Conditions are ANDed таким образом, чтобы была показана короткая резка?

Что относительно нескольких MultiDataTriggers? Являются ли они закорочены так, что первый полностью удовлетворен, поэтому оценка прекращается? Или все они оцениваются с последним выигрышем, если несколько удовлетворяются?

+0

Обратите внимание, что это НЕ НАСТОЯЩИЙ вопрос, основанный на мнениях, просто трудно найти окончательную информацию по этой конкретной теме. – slugster

ответ

6

Triggers are evaluated from top to bottom. Это верно для всех видов триггеров (Trigger, DataTrigger, MultiTrigger и MutliDataTrigger).

Как насчет нескольких MultiDataTriggers? Являются ли они закорочены так, что , что первый полностью удовлетворен, вызывает остановку оценки? Или все они оцениваются с последним выигрышем, если несколько удовлетворяются?

Как указано, триггеры оцениваются сверху вниз. Таким образом, в случае, если первый удовлетворяет всем условиям, это не означает, что дальнейшие триггеры не будут оцениваться. Все триггеры, применяемые к измененному свойству, оцениваются, и в случае, если любые два из них устанавливают одно и то же свойство внутри триггера, тогда last trigger always won и overrides the property set by first trigger.

<TextBlock> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
      <Style.Triggers> 
      <DataTrigger Binding="{Binding IsEnable}" Value="True"> 
       <Setter Property="Text" Value="Test1"/> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding IsEnable}" Value="True"> 
       <Setter Property="Text" Value="Test2"/> 
      </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 

Текст всегда будет Test2 когда IsEnable оценивает, чтобы быть правдой.


Можно ли авторитетно заявить, как MultiDataTriggers составляются? I понимают, что условия AND вместе, это скомпилировано в таким образом, чтобы была показана короткая резка?

Да, короткая резка представлена ​​в MultiDataTrigger, то есть если first condition evaluate to be false, second condition won't be checked. Этот пример подтверждает это -

<TextBlock> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
      <Style.Triggers> 
       <MultiDataTrigger> 
        <MultiDataTrigger.Conditions> 
         <Condition Binding="{Binding IsEnable, 
          Converter={StaticResource SingleValueConverter}}" 
            Value="True"/> 
         <Condition Binding="{Binding IsEnable, 
          Converter={StaticResource SingleValueConverter}}" 
            Value="True"/> 
        </MultiDataTrigger.Conditions> 
        <Setter Property="Text" Value="Test"/> 
       </MultiDataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 

В обоих условиях применяется преобразователь, но в случае, если это IsEnabledfalse, converter gets hit only once потому, что первое условие оценивает, чтобы быть ложным. Но в случае, если IsEnabled - это true, converter gets hit twice, так как первое условие успешно встречается.

+3

Спасибо, хороший ответ. Примеры вроде этого так же хороши, как ссылки на MSDN :) – slugster

1

Преобразователи позволяют отлаживать и более сложные логики, но они также должны проверять все свои Bindings и вызывать внешнюю функцию каждый раз при изменении одного из их Bindings. Поэтому они почти медленнее, чем триггеры. Триггеры останавливаются при первом невыполненном условии.

Так что я должен ответить с MutiDataTrigger как можно больше, если вам нужно больше логики, в зависимости от того, возможно ли, что некоторые условия повторяются в другом месте или нет, вы можете выбрать дополнительный DependencyProperty (который изменяется, когда некоторые другие свойства изменяются) или использовать конвертер.

Например, у меня есть 5 свойств, которые я хочу связываться с:

IsChecked = A && B && (C || D || !E) 
IsReadonly = !A && !B && (C || D || !E) 

, так что я бы создать новое свойство F, равное C || D || !E, и когда один из этих трех изменений, обновление F. теперь я могу использовать F как третий путь привязки триггера.

+0

Спасибо за ответ, я не уверен, что вы поняли все последствия того, что я просил? @Rohits ответ показывает, что мне нужно будет перейти на конвертер, потому что: а) эти мультитатагергеры находятся на сетке, которая уже дьявольски медленна; б) многоточечные усилители увеличивают риск ошибок привязки и в) я хочу избежать сложных свойств, потому что связанным объектам уже достаточно их, и им легко стать медленными из-за плохого кодирования dev. Если бы я использовал сложные свойства, тогда я мог бы также использовать конвертер, специально предназначенный для этой конкретной привязки. – slugster

+0

Но, сказав, что ваш ответ может быть полезен для тех, кто использует ограниченное количество мультитатрикеров, но хочет упростить условия в них. – slugster