DataTrigger, где значение не равно null?
Я знаю, что я могу сделать сеттер, который проверяет, если значение равно 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. Однако выбранный ответ показывает, вероятно, лучший способ создать такого рода функциональность. Хорошая находка.
12 ответов:
Я столкнулся с подобным ограничением с помощью DataTriggers, и, казалось бы, вы можете проверить только равенство. Самое близкое, что я видел, что может помочь вам, - это техника для выполнения других типов сравнений, отличных от равенства.
этот блог описывается, как делать сравнения, такие как ЛТ, ГТ, и т. д. В DataTrigger.
Это ограничение DataTrigger можно обойти в некоторой степени с помощью преобразователя для массажа данных в a особое значение вы можете сравнить с тем, как это было предложено в ответе Роберта Макни.
Вы можете использовать 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."); } }
Это немного чит, но я просто задать стиль по умолчанию, а затем преодолел его с помощью 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>
сравните с null (как сказал Майкл Нунан):
<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>
Я использую это только для включения кнопки, если выбран элемент listview (т. е. не null):
<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>
можно использовать
DataTrigger
класс Microsoft.Выражение.Взаимодействия.dll, которые приходят с Выражение Blend.Код:
<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>
С помощью этого метода вы можете вызвать против
GreaterThan
иLessThan
тоже. Чтобы использовать этот код, вы должны ссылаться на две dll:
<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>
Я просто использовал обратную логику здесь...установка моего stackpanel невидимым, когда мой comboitem не заполнен, он работает довольно хорошо!
стоп! Нет конвертера! Я не хочу "продавать" библиотеку этого парня, но я ненавидел тот факт, что делаю конвертер каждый раз, когда я хотел сравнить материал в XAML.
Итак, с этой библиотекой:https://github.com/Alex141/CalcBinding
вы можете сделать это [и многое другое] :
во-первых, в объявлении windows / userControl:
<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 к проекту).
мое решение находится в экземпляре DataContext (или ViewModel при использовании MVVM). Я добавляю свойство, которое возвращает true, если выполняется условие Not Null, которое я хочу.
Public ReadOnly Property IsSomeFieldNull() As Boolean Get Return If(SomeField is Null, True, False) End Get End Property
и привязать DataTrigger к указанному выше свойству. Примечание: In VB.NET обязательно используйте оператор If, а не функцию IIf, которая не работает с нулевыми объектами. Тогда XAML-это:
<DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False"> <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" /> </DataTrigger>
конвертер:
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}}"
Вы можете использовать конвертер или создать новое свойство в ViewModel так:
public bool CanDoIt { get { return !string.IsNullOrEmpty(SomeField); } }
и использовать его:
<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
Если вы ищете решение, которое не использует 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>