2008-12-10 52 views
134

我知道我可以創建一個setter來檢查值是否爲NULL並執行某些操作。例如:DataTrigger的值不爲null?

<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> 

但是我該如何檢查「不是」值......如「NOT NULL」或「NOT = 3」?這在XAML中可能嗎?

結果:感謝您的回答......我知道我可以做一個值轉換器(這意味着我將不得不在代碼中,並且不會像我所希望的那樣是純XAML)。但是,這確實回答了有效「否」的問題,您無法在純XAML中執行此操作。但是,選擇的答案顯示可能是創建那種功能的最佳方式。很好的發現。

回答

32

我遇到了DataTriggers類似的限制,似乎你只能檢查是否相等。我所見過的最接近的東西可能會幫助你做一種除平等之外的其他類型比較的技術。

This blog post描述瞭如何在DataTrigger中比較LT,GT等。

這個數據觸發器的限制可以在一定程度上通過使用一個轉換器將數據按摩到一個特殊的值,然後可以與之比較,如Robert Macnee的答案中所建議的。

+9

有趣的是DataTrigger實際上有一個內部字段wh它控制它是否測試是否相等。不幸的是,你必須做一個合理的反思才能到達必需的領域。問題是它可能會在下一個.net版本中崩潰。 – 2009-02-27 04:22:12

127

您可以使用此一的IValueConverter:

<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在別處定義(和CONV設置爲引用其命名空間):

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."); 
    } 
} 

一個更普遍的解決辦法是實施一個IValueConverter,它檢查ConverterParameter是否相等,這樣你就可以檢查任何東西,而不僅僅是null。

+6

我想你可以使轉換器更通用一些,並使用ConverterParameter來傳遞一個值來比較(爲了支持這兩個比較NOT NULL和NOT 3. – 2008-12-10 16:56:46

+0

這對我來說是一種享受 - 使用多觸發器,它使它更好,更強大 – Bertie 2015-07-28 13:10:41

120

這是一個有點作弊的,但我只設置一個默認的樣式,然後使用DataTrigger如果該值爲null推翻它...

<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

這是我的場景的最佳解決方案!感謝您提供這個答案! – Scott 2010-03-24 21:39:26

+11

我不認爲這是一個黑客,你需要做很多時間;這是最乾淨 – akjoshi 2011-11-29 14:44:29

14

我使用這個,只啓用一個按鈕如果一個列表視圖項目被選擇(即不爲空):

<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> 
3

我的解決辦法是在DataContext的實例(或者如果使用MVVM視圖模型)。如果符合我想要的Not Null條件,則添加一個返回true的屬性。

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

並將DataTrigger綁定到上述屬性。 注意:在VB.NET中,一定要使用運算符If和NOT IIf函數,它不適用於Null對象。 那麼XAML是:

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

與空比較(正如邁克爾·努南說):

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

與NOT NULL比較(無需轉換器):

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

轉換器:

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

綁定:

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

可以在Microsoft.Expression.Interactions.dll附帶Expression Blend中使用DataTrigger類。

代碼示例:

<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> 

使用這種方法,你可以觸發對GreaterThanLessThan了。 爲了使用此代碼,您應該引用這兩個dll的:

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> 

我只是用反邏輯在這裏...當我的comboitem沒有填充時,將我的堆棧面板設置爲不可見,它工作得非常好!

5

停!沒有轉換器!我不想「出售」這個傢伙的圖書館,但我討厭每次我想比較XAML中的東西時做轉換器的事實。

所以用這個庫:https://github.com/Alex141/CalcBinding

你能做到這一點[和更多]:

首先,在Windows的報關/用戶控件:

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

然後,在文本塊

<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> 

魔法部分是conv:綁定'MYValue == null'。事實上,你可以設置你想要的任何條件[看看文檔]。

請注意,我不是第三方的粉絲。但這個庫是免費的,影響不大(只需將2個.dll添加到項目中)。

2

您可以使用轉換器或創建一樣,在您的視圖模型的新屬性:

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

,並使用它:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}"> 
2

如果您正在尋找不使用的IValueConverter一個解決方案,你總是可以用下面的機制

 <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>