DataTrigger nerede değer null DEĞİL?


163

Ben bir değerin NULL olup olmadığını kontrol etmek ve bir şeyler yapmak kontrol eden bir ayarlayıcı yapabileceğini biliyorum. Misal:

<TextBlock>
  <TextBlock.Style>
    <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding SomeField}" Value="{x:Null}">
          <Setter Property="TextBlock.Text" Value="It's NULL Baby!" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>
</TextBlock>

Ama "DEĞİL DEĞİL" veya "DEĞİL = 3" gibi bir "değil" değeri nasıl kontrol edebilirim? Bu XAML'de mümkün mü?

Sonuçlar: Cevaplarınız için teşekkürler ... Bir değer dönüştürücüsü yapabileceğimi biliyordum (bu, kodda gitmek zorunda kalacağım ve umduğum gibi saf XAML olmaz). Ancak bu, etkili bir şekilde "hayır" sorusunu saf XAML'de yapamayacağınız soruyu yanıtlar. Bununla birlikte, seçilen cevap muhtemelen bu tür bir işlevsellik oluşturmanın en iyi yolunu göstermektedir . İyi bulmak.

Yanıtlar:


42

DataTriggers ile benzer bir sınırlamaya koştum ve sadece eşitliği kontrol edebileceğiniz anlaşılıyor. Size yardımcı olabilecek en yakın şey, eşitlik dışında başka tür karşılaştırmalar yapmak için bir tekniktir.

Bu blog gönderisi , bir DataTrigger'da LT, GT, vb. Karşılaştırmaları nasıl yapacağınızı açıklar.

DataTrigger'ın bu sınırlaması, Robert Macnee'nin cevabında önerildiği gibi, verileri daha sonra karşılaştırabileceğiniz özel bir değere masaj yapmak için bir Dönüştürücü kullanılarak bir ölçüde çözülebilir.


10
İlginçtir ki, DataTrigger aslında eşitliği test edip etmediğini kontrol eden bir dahili alana sahiptir. Maalesef gerekli alana ulaşmak için makul miktarda yansıma yapmanız gerekiyor. Sorun, .net'in sonraki sürümünde kırılabilmesidir.
Caleb Vear

155

Bunun için bir IValueConverter kullanabilirsiniz:

<TextBlock>
    <TextBlock.Resources>
        <conv:IsNullConverter x:Key="isNullConverter"/>
    </TextBlock.Resources>
    <TextBlock.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeField, Converter={StaticResource isNullConverter}}" Value="False">
                    <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

IsNullConverter başka bir yerde tanımlandığında (ve conv, ad alanına başvuru yapacak şekilde ayarlanır):

public class IsNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("IsNullConverter can only be used OneWay.");
    }
}

Daha genel bir çözüm, ConverterParameter ile eşitliği kontrol eden bir IValueConverter uygulamaktır, böylece sadece null değil, her şeye karşı kontrol edebilirsiniz.


6
Sana biraz daha genel ve kullanım ConverterParameter hem DEĞİL boş karşılaştırarak ve NOT 3. desteklemek amacıyla (karşılaştırmak için bir değer geçirir için dönüştürücü yapmak herhalde
J c

Bu benim için bir tedavi yaptı - Çoklu Tetik kullanarak, güzel ve güçlü hale getiriyor.
Bertie

150

Bu biraz hile ama sadece varsayılan bir stil ayarlamak ve sonra değer null ise bir DataTrigger kullanarak overrode ...

  <Style> 
      <!-- Highlight for Reviewed (Default) -->
      <Setter Property="Control.Background" Value="PaleGreen" /> 
      <Style.Triggers>
        <!-- Highlight for Not Reviewed -->
        <DataTrigger Binding="{Binding Path=REVIEWEDBY}" Value="{x:Null}">
          <Setter Property="Control.Background" Value="LightIndianRed" />
        </DataTrigger>
      </Style.Triggers>
  </Style>

1
Bu benim senaryom için en iyi çözümdü! Bu yanıtı sağladığınız için teşekkürler!
Scott

14
Bunun bir hack olduğunu düşünmüyorum, bunu çok zaman yapmanız gerekiyor; ve bunu yapmanın en temiz yolu.
akjoshi

3
Varsayılan Ayarlayıcı Style.Setter etiketi olmadan kullanılabilir.
Naser Asadi

1
Sadece bilet! Stili sahip olan kontrole varsayılanı koymaya devam ettim ve neden stillerimi geçersiz kılmaya devam ettiğini anlayamadım :-) Teşekkürler!
Riegardt Steyn

2
bir dönüştürücü kullanarak çok daha iyi cevap ... basit ve temiz.
DasDas

27

Null ile karşılaştır (Michael Noonan'ın dediği gibi):

<Style>
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
     </Style.Triggers>
</Style>

Boş değil ile karşılaştır (dönüştürücü olmadan):

<Style>
    <Setter Property="Visibility" Value="Collapsed" />
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
     </Style.Triggers>
</Style>

4
Bu açık ara en doğru cevaptır. Bunu sevdim!
TimothyP

15

Sadece bir liste görünümü öğesi seçili ise (yani null değil) bir düğmeyi etkinleştirmek için kullanıyorum:

<Style TargetType="{x:Type Button}">
    <Setter Property="IsEnabled" Value="True"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding ElementName=lvMyList, Path=SelectedItem}" Value="{x:Null}">
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

4
Bazen en basit çözüm net bir şekilde gizlenir. XAML kodunun yukarıdan aşağıya yorumlandığına inanıyorum. Bu şekilde, liste görünümünde hiçbir öğe seçilmezse düğme önce etkinleştirilir ve ardından devre dışı bırakılır. Ama lütfen söyle, liste görünümünde bir öğe seçildikten sonra stil güncelleniyor mu?
froeschli

Bir liste öğesi seçildiğinde düğme etkinleştirilir, evet.
SteveCav

14

Expression Blend ile birlikte gelen Microsoft.Expression.Interactions.dllDataTrigger içindeki sınıfı kullanabilirsiniz .

Kod Örneği:

<i:Interaction.Triggers>
    <i:DataTrigger Binding="{Binding YourProperty}" Value="{x:Null}" Comparison="NotEqual">
       <ie:ChangePropertyAction PropertyName="YourTargetPropertyName" Value="{Binding YourValue}"/>
    </i:DataTrigger
</i:Interaction.Triggers>

Bu yöntemi kullanarak GreaterThanve karşı tetikleyebilirsiniz LessThan. Bu kodu kullanmak için iki dll referans vermelisiniz:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll


6
<StackPanel.Style>
  <Style>
    <Setter Property="StackPanel.Visibility" Value="Visible"></Setter>
    <Style.Triggers>
      <DataTrigger  Binding="{Binding ElementName=ProfileSelectorComboBox, Path=SelectedItem.Tag}" Value="{x:Null}">
          <Setter Property="StackPanel.Visibility" Value="Collapsed"></Setter>
      </DataTrigger>
    </Style.Triggers>
  </Style>
</StackPanel.Style>

Buradaki ters mantığı kullandım ... komboitem doldurulmadığında yığın panelimi görünmez olarak ayarladım, oldukça iyi çalışıyor!


6

Dur! Dönüştürücü yok! Bu adamın kütüphanesini "satmak" istemiyorum, ama XAML'deki şeyleri karşılaştırmak istediğim her seferinde dönüştürücü yapmaktan nefret ediyorum.

Bu kütüphane ile: https://github.com/Alex141/CalcBinding

bunu [ve çok daha fazlasını] yapabilirsiniz:

İlk olarak, windows / userControl bildiriminde:

<Windows....
     xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding"
>

sonra, metin bloğunda

<TextBlock>
      <TextBlock.Style>
          <Style.Triggers>
          <DataTrigger Binding="{conv:Binding 'MyValue==null'}" Value="false">
             <Setter Property="Background" Value="#FF80C983"></Setter>
          </DataTrigger>
        </Style.Triggers>
      </TextBlock.Style>
    </TextBlock>

Sihirli kısım konv: 'MYValue == null' bağlanması . Aslında, istediğiniz herhangi bir koşulu ayarlayabilirsiniz [dokümana bakın].

üçüncü tarafın hayranı olmadığımı unutmayın. ancak bu kütüphane ücretsizdir ve çok az etkisi vardır (sadece projeye 2 .dll ekleyin).


5

Benim çözüm DataContext örneğinde (veya MVVM kullanılıyorsa ViewModel). İstediğim Boş Değil koşulu karşılandığında true döndüren bir özellik eklerim.

    Public ReadOnly Property IsSomeFieldNull() As Boolean
        Get
            Return If(SomeField is Null, True, False)
        End Get
    End Property

ve DataTrigger öğesini yukarıdaki özelliğe bağlayın. Not: VB.NET'te, Null nesneleriyle çalışmayan IIf işlevi If ve NOT işlevini kullandığınızdan emin olun. O zaman XAML:

    <DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
      <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
    </DataTrigger>

3

IValueConverter kullanmayan bir çözüm arıyorsanız, her zaman aşağıdaki mekanizma ile gidebilirsiniz

       <StackPanel>
            <TextBlock Text="Border = Red when null value" />
            <Border x:Name="border_objectForNullValueTrigger" HorizontalAlignment="Stretch" Height="20"> 
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Background" Value="Black" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ObjectForNullValueTrigger}" Value="{x:Null}">
                                <Setter Property="Background" Value="Red" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
            <TextBlock Text="Border = Green when not null value" />
            <Border HorizontalAlignment="Stretch" Height="20">
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Background" Value="Green" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Background, ElementName=border_objectForNullValueTrigger}" Value="Red">
                                <Setter Property="Background" Value="Black" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
            <Button Content="Invert Object state" Click="Button_Click_1"/>
        </StackPanel>

2

Dönüştürücü:

public class NullableToVisibilityConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Collapsed : Visibility.Visible;
    }
}

Bağlama:

Visibility="{Binding PropertyToBind, Converter={StaticResource nullableToVisibilityConverter}}"

2

ViewModel'inizde bir dönüştürücü kullanabilir veya yeni özellik oluşturabilirsiniz:

public bool CanDoIt
{
    get
    {
        return !string.IsNullOrEmpty(SomeField);
    }
}

ve kullanın:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.