programing

WPF - Data Trigger와 트리거를 조합하는 방법

javajsp 2023. 4. 19. 22:14

WPF - Data Trigger와 트리거를 조합하는 방법

주의: 관련 질문을 했습니다.DataTrigger와 EventTrigger를 결합하는 방법

몇 가지 아이템이 들어 있는 리스트 박스가 있습니다.아이템의 클래스 구현INotifyPropertyChanged그리고 소유물이 있다.IsAvailable이 속성을 사용하여 목록에서 사용할 수 없는 옵션을 다른 색으로 표시합니다.

그러나 선택한 항목을 사용할 수 없는 경우 전경색이 빨간색이어야 합니다.

<ListBox>
  <ListBox.Resources>
    <DataTemplate DataType="{x:Type local:InstitutionViewModel}">
      <TextBlock Name="Name" Text="{Binding Name}"/>
      <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsAvailable}" Value="False">
          <Setter TargetName="Name" Property="Foreground" Value="#888"/>
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </ListBox.Resources>
</ListBox>

위의 데이터 트리거를 사용하여 사용할 수 없는 항목을 회색으로 표시합니다.

제가 직면하고 있는 문제는 아이템이 선택되었다는 사실이 템플릿이 바인딩되어 있는 기본 데이터와 무관하다는 것입니다.제가 정말 원하는 것은 일반적인 두 가지 기능을 모두 지원하는 일종의 멀티 트리거입니다.Trigger종속 속성(ListBoxItem.IsSelected)와 함께DataTrigger바인드된 데이터 항목.

뷰 모델에 선택 개념을 도입하지 않고 이 작업을 수행할 수 있습니까?

사용할 수 없는 아이템을 무효로 하지 않는 이유에 대해서는, 사용할 수 없는 옵션을 선택할 수 있는 것이 애플리케이션의 요건인 것을 이해해 주세요.실제로 몇 개의 리스트 박스가 있으며, 한 박스에서 선택하면 다른 박스에서 사용할 수 있는 것이 영향을 받습니다.이전 선택에 따라 아이템을 비활성화하면 사용자가 마음을 바꾸거나 다른 조합을 탐색할 수 없기 때문에 아이템을 비활성화할 수 없습니다.

이 문제에 직면한 다른 사람들을 위해, 나는 나에게 맞는 해결책을 찾았다.물론, 나는 여전히 다른 흥미로운 대답들을 보는 것에 관심이 있다.

제가 한 일은 다음과 같습니다.

<MultiDataTrigger>
  <MultiDataTrigger.Conditions>
    <Condition Binding="{Binding
      RelativeSource={
        RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
        Path=IsSelected}" Value="True"/>
    <Condition Binding="{Binding IsAvailable}" Value="False"/>
  </MultiDataTrigger.Conditions>
  <Setter TargetName="Name" Property="Foreground" Value="#F00"/>
</MultiDataTrigger>

멀티 트리거라고 해서 특별한 것은 없습니다.데이터 템플릿에서 선택한 항목의 스타일을 다르게 하려면 다음을 사용할 수 있습니다.

<DataTrigger Binding="{Binding 
  RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
    Path=IsSelected}" Value="True">
  <Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>

함께 사용하기 위해DataGridRow바인딩 모드를 로 변경하다Self:

Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=... 

DevExpress GridControl의 경우 필드 값 형식 조건과 행 IsFocused 속성을 결합하는 가 있습니다.

XAML:

<dxg:GridControl.View>
    <dxg:TableView CustomRowAppearance="CustomRowAppearance" NavigationStyle="Row"> 
        <dxg:TableView.FormatConditions> 
            <dxg:DataBarFormatCondition FieldName="Profit" PredefinedFormatName="GreenGradientDataBar" /> 
            <dxg:FormatCondition FieldName="Profit" Expression="[Profit]&lt;0" PredefinedFormatName="RedText"/> 
            <dxg:FormatCondition FieldName="Profit" Expression="[Profit]&gt;=0" PredefinedFormatName="GreenText"/> 
            <dxg:FormatCondition FieldName="Profit" Expression="[Profit]&lt;=0" PredefinedFormatName="LightRedFillWithDarkRedText" ApplyToRow="True"/> 
        </dxg:TableView.FormatConditions> 
    </dxg:TableView>
</dxg:GridControl.View>

C#:

void CustomRowAppearance(object sender, CustomRowAppearanceEventArgs e) {
    if (e.RowSelectionState != SelectionState.None) {
        object result = e.ConditionalValue;
        if (e.Property == TextBlock.ForegroundProperty || e.Property == TextBlock.BackgroundProperty) {
            SolidColorBrush original = e.OriginalValue as SolidColorBrush;
            SolidColorBrush conditional = e.ConditionalValue as SolidColorBrush;
            if (conditional != null && (original == null || original.Color != conditional.Color))
                result = ShadeBrush(conditional);
        }
        e.Result = result;
        e.Handled = true;
    }
}

SolidColorBrush ShadeBrush(SolidColorBrush brush) {
    Color originalColor = brush.Color;
    float coefficient = 0.75f;
    byte a = originalColor.A;
    if (!grid.IsKeyboardFocusWithin) // I commented this line in WPF
        a = (byte)(originalColor.A / 2);
    byte r = (byte)(originalColor.R * coefficient);
    byte g = (byte)(originalColor.G * coefficient);
    byte b = (byte)(originalColor.B * coefficient);
    return new SolidColorBrush(Color.FromArgb(a, r, g, b));
}

언급URL : https://stackoverflow.com/questions/602517/wpf-how-to-combine-datatrigger-and-trigger