WPF에서 데이터 트리거에 여러 조건을 제공하려면 어떻게해야합니까?


답변:


280

MultiDataTrigger 유형 사용

<Style TargetType="ListBoxItem">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Path=State}" Value="WA">
        <Setter Property="Foreground" Value="Red" />
      </DataTrigger>    
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding Path=Name}" Value="Portland" />
          <Condition Binding="{Binding Path=State}" Value="OR" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Background" Value="Cyan" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>

28
multiTrigger에서 "OR"문을 수행하는 방법이 있습니까? 예를 들어 이름 = "포틀랜드"또는 주 = "OR"
jasonk

12
@jasonk-MultiTrigger로 그렇게 할 수 있는지 확실하지 않습니다. 이를 위해 두 가지 트리거를 정의 할 수 있습니다.
Gishu

2
간단한 OR 조건문 인 경우 논리를 반대로하여 AND로 바뀔 수 있습니다. | 조건 1 | 조건 2 | 결과 | | true | true | 참 | | true | false | 참 | | 거짓 | 참 | 참 | | 거짓 | 거짓 | 거짓 | 둘 중 하나만 확인하는 대신 둘 다가 거짓인지 확인하고 기본값을 true로 설정하십시오.
WeSam Abdallah

3
@WeSamAbdallah 조건이 거짓인지 확인할 수 없습니다.
Jim Balter

4
간단한 변환기로 조건이 거짓인지 확인할 수 있습니다.
Paul

50

@jasonk- "또는"을 원하면 (A와 B) 이후 모든 조건을 무효화하십시오. <=> ~ (~ A 또는 ~ B)

그러나 부울 이외의 값이 있으면 유형 변환기를 사용해보십시오.

<MultiDataTrigger.Conditions>
    <Condition Value="True">
        <Condition.Binding>
            <MultiBinding Converter="{StaticResource conditionConverter}">
                <Binding Path="Name" />
                <Binding Path="State" />
            </MultiBinding>
        </Condition.Binding>
        <Setter Property="Background" Value="Cyan" />
    </Condition>
</MultiDataTrigger.Conditions>

Convert 메서드의 값을 원하는 방식으로 원하는 방식으로 사용할 수 있습니다.


3
아, 스마트 무효화의 모든으로 이동하고, OR 조건 :)에 플립
myermian

8
이 답변을 조금 확장 해 주시겠습니까? 사용 방법을 잘 모르겠습니다. 무엇을 conditionConverter합니까? or이 예제에서 "포틀랜드"와 "OR"을 두 가지 옵션 으로 어떻게 지정 합니까?
DLeh

4
@ cod3monk3y, 링크가 깨졌습니다.
Spidermain50

22

@serine의 답변 을 자세히 설명하고 사소한 다중 값 조건을 사용하여 작업하는 방법을 설명하려면 부울 조건의 항목에 "dim-out"오버레이를 표시해야합니다 NOT a AND (b OR NOT c).

배경은 "다중 선택"질문입니다. 사용자가 오답을 선택하면 비활성화됩니다 (흐리게 표시되어 다시 선택할 수 없음). 자동 상담원은 설명을하기 위해 특정 선택에 집중할 수 있습니다 (테두리 강조 표시). 상담원이 항목에 초점을 맞추면 비활성화되어 있어도 흐리게 표시해서는 안됩니다 . 집중에없는 모든 항목이 표시됩니다 -집중 드 , 밖으로 흐리게한다.

디밍의 논리는 다음과 같습니다.

NOT IsFocused AND (IsDefocused OR NOT Enabled)

이 논리를 구현하기 위해 논리 IMultiValueConverter와 일치하도록 (어색하게) 일반 이름을 만들었습니다.

// 'P' represents a parenthesis
//     !  a &&  ( b ||  !  c )
class NOT_a_AND_P_b_OR_NOT_c_P : IMultiValueConverter
{
    // redacted [...] for brevity
    public object Convert(object[] values, ...)
    {
        bool a = System.Convert.ToBoolean(values[0]);
        bool b = System.Convert.ToBoolean(values[1]);
        bool c = System.Convert.ToBoolean(values[2]);

        return !a && (b || !c);
    }
    ...
}

XAML에서는 리소스 MultiDataTrigger에서 이것을 사용 <Style><Style.Triggers>합니다.

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <!-- when the equation is TRUE ... -->
        <Condition Value="True">
            <Condition.Binding>
                <MultiBinding Converter="{StaticResource NOT_a_AND_P_b_OR_NOT_c_P}">
                    <!-- NOT IsFocus AND ( IsDefocused OR NOT Enabled ) -->
                    <Binding Path="IsFocus"/>
                    <Binding Path="IsDefocused" />
                    <Binding Path="Enabled" />
                </MultiBinding>
            </Condition.Binding>
        </Condition>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.Setters>
        <!-- ... show the 'dim-out' overlay -->
        <Setter Property="Visibility" Value="Visible" />
    </MultiDataTrigger.Setters>
</MultiDataTrigger>

그리고 완전성을 위해 내 변환기는 ResourceDictionary

<ResourceDictionary xmlns:conv="clr-namespace:My.Converters" ...>
    <conv:NOT_a_AND_P_b_OR_NOT_c_P x:Key="NOT_a_AND_P_b_OR_NOT_c_P" />
</ResourceDictionary>

11
이것이 이것이 변환기를 이런 식으로 사용하려는 의도는 아니라고 생각합니다. 실제로 표시 할 값을 변환하기위한 것입니다. 이것이 복잡해지면 뷰 모델에서 계산 된 속성을 만들어 필요한 것을 제공하십시오.
Martin Capodici

13
그래도 명명
켈리 엘튼

13
프로그래밍이 공예 였고 코드가 우아했을 때를 기억하기 위해 잠시 침묵하십시오.
퍼지 로직

0

이 답변은 애니메이션에만 해당


됩니다. AND 로직을 구현하려면 MultiTrigger를 사용해야합니다. 다음은 예입니다.

Text = ""(빈 문자열) AND IsKeyboardFocused = "False" 속성 인 경우 몇 가지 작업을 수행하려고한다고 가정합니다. 코드는 다음과 같아야합니다.

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <!-- Your actions here -->
        </MultiTrigger.EnterActions>
</MultiTrigger>

OR 로직을 구현하려면 몇 가지 방법이 있으며 수행하려는 작업에 따라 다릅니다.

첫 번째 옵션은 여러 트리거를 사용하는 것입니다.
따라서 Text = "" OR IsKeyboardFocused = "False"인
경우 무언가를 수행하려고한다면 코드는 다음과 같아야합니다.

<Trigger Property="IsEnabled" Value="false">
    <Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
    <Setter Property="BorderBrush" TargetName="border" 
            Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>


그러나 이것의 문제는 Text IS N'T null OR IsKeyboard = "True"인 경우에 무언가를하고 싶다면 어떻게해야 합니까? 이것은 두 번째 접근 방식으로 달성 할 수 있습니다.
De Morgan의 규칙을 기억하십시오. 즉! (! x &&! y) = x || 와이.
따라서 Text = ""및 IsKeyboard = "True"일 때 트리거되는 다중 트리거를 작성하여 이전 문제를 해결하는 데 사용하고 EXIT ACTIONS 에서 다음과 같이 조치를 수행 합니다.

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.ExitActions>
        <!-- Do something here -->
    </MultiTrigger.ExitActions>
</MultiTrigger>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.