Мне интересно, могу ли я установить для свойства IsVisible элемента xaml значение true, если логическое значение связанного свойства равно false?
В зависимости от значения логического свойства я хочу условно отображать разные элементы в представлении.
Это мой код:
<ContentPage ...
x:Name = "page">
<ListView BindingContext = "{x:Reference page}" ItemSource = "digitalInputs">
<ListView.ItemTemplate>
<DataTemplate x:DataType = "services:DigitalInput">
<ViewCell>
<HorizontalStackLayout>
<!-- This seems to be working. Render a green ball, if boolean value is true -->
<Image Source = "ballgreen" IsVisible = "{Binding value}"/>
<!-- Doesn't work. I want to render a red ball if the boolean value is false. -->
<Image Source = "ballred" IsVisible = "{Binding !value}"/>
<Label Text = "{Binding valueText}" />
</HorizontalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
Я подумал о том, чтобы добавить еще одно логическое свойство в класс DigitalInput и установить его значение, противоположное value
, но, с другой стороны, я не хочу трогать этот класс, поскольку он моделирует 1:1, как я извлекаю данные из сети. услуга.
Я также думал о добавлении конвертера, но я не знаю, как это сделать в отношении BindingContext
. Я надеюсь, что кто-то может помочь и пролить свет на этот вопрос для меня.
С уважением.
Есть несколько способов сделать это, как вы уже упоминали сами. Самый простой способ: добавить инвертированное свойство в вашу модель. Не самый элегантный вариант.
В самом XAML у вас не может быть никакой логики, поэтому оператор !
не будет работать. Преобразователь действительно путь.
Чтобы реализовать IValueConverter
, что вам нужно в данном случае, создайте класс, реализующий этот интерфейс. Когда вы это сделаете, есть несколько методов, которые вам нужно реализовать. В этом случае это довольно просто, поскольку оно просто инвертирует логическое значение.
Однако, поскольку это XAML и все основано на строках, чтобы сделать его действительно надежным, вы можете принять во внимание некоторую обработку ошибок. В этом случае я выберу счастливый путь. Найдите пример реализации ниже:
public class InverseBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !((bool)value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
// Converting back rarely happens, a lot of the converters will throw an exception
//throw new NotImplementedException();
}
}
Этот код взят из этого SO вопроса.
Чтобы теперь использовать его в своем XAML, сделайте следующее: <Image Source = "ballred" IsVisible = "{Binding value, Converter = {converters:InverseBoolConverter}}"/>
И вам нужно будет добавить запись xmlns
в корень вашей страницы, например: xmlns:converters = "clr-namespace:YourProject.Namespace"
. Убедитесь, что YourProject.Namespace
соответствует пространству имен InverseBoolConverter
выше.
Хорошая новость в том, что вам не нужно ничего этого делать! Это встроено в набор инструментов сообщества .NET MAUI. Вы можете просто установить пакет NuGet, использовать этот конвертер, и вы уже в пути.
Найдите документацию для этого на этой странице.
Этот ответ решил проблему для меня. Я уже построил такой преобразователь, просто не знал, как его правильно привязать к элементу. Я использую свойство IsVisible, которое принимает аргумент логического типа. Спасибо!
Похоже, вам нужен
IValueConverter
. Посмотрите здесь