У меня есть объект Dto:
public class SearchResultDto
{
public bool IsOne { get; set; };
public bool IsTwo { get; set; }
}
И у меня есть расширение метода:
public static class SearchResultDtoExtension{
public static bool IsBoth(this SearchResultDto dto)
{
return dto.IsOne && dto.IsTwo;
}
}
В моей ViewModel я могу успешно использовать searchResultDto.IsBoth();
Я хочу, чтобы это расширение использовалось в xaml, например:
IsVisible = {Binding IsBoth()}
Это не работает.
Как я могу использовать расширение метода в xaml?
мой код:
<listView:SfListView.ItemTemplate>
<DataTemplate x:DataType = "contracts:SearchResultDto">
<VerticalStackLayout IsVisible = "{Binding **IsBoth()**}"
Ну, только общедоступные свойства являются привязываемыми, а методы — нет. Вам нужно будет создать другое свойство, которое вызывает метод, например. авто-свойство. Общая рекомендация: лучше не использовать DTO непосредственно в качестве класса модели в MVVM. Вам следует создать отдельный класс для модели, а затем сопоставить DTO и модель. Таким образом, вы можете расширять и обновлять модель в соответствии с вашими потребностями, не меняя DTO.
Как объяснено в комментариях, вы не можете связывать методы в XAML, вместо этого вы можете использовать один из двух подходов:
ValueConverter
:public class IsBothConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
=> (value as SearchResultDto)?.IsBoth();
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<ContentPage.Resources>
<ResourceDictionary>
<local:IsBothConverter x:Key = "isBothConverter" />
</ResourceDictionary>
</ContentPage.Resources>
...
<VerticalStackLayout IsVisible = "{Binding ., Converter = {StaticResource isBothConverter}}" />
Both
внутри вашей ViewModel:
Обратите внимание: всякий раз, когда изменяется свойство типа SearchResultDto
, мы также вызываем событие изменения свойства для свойства Both
.SearchResultDto dto = new() { IsOne = true, IsTwo = true };
public SearchResultDto Dto
{
get => dto;
set
{
dto = value;
OnPropertyChanged(nameof(Dto));
OnPropertyChanged(nameof(Both));
}
}
public bool Both => (dto is null) ? false : dto.IsOne && dto.IsTwo;
Я вижу, что вы находитесь внутри datatemplate
, поэтому вам необходимо убедиться в правильности Source
и x:DataType
при привязке к Both
:
<VerticalStackLayout IsVisible = "{Binding Path = "Both", Source = "..."}" />
public class SearchResultDto
{
public bool IsOne { get; set; }
public bool IsTwo { get; set; }
public bool IsBoth => IsOne && IsTwo;
}
<VerticalStackLayout IsVisible = "{Binding IsBoth}" />
Просто предложение: возможно, также включите способ сделать это без прямого использования DTO в представлении.
@Джулиан, ты имеешь в виду без изменения класса SearchResultDto
, добавив IsBoth
?
Да, потому что автоматические свойства обычно не являются частью DTO, поскольку идея наличия DTO на самом деле представляет собой просто передачу данных, и, как правило, DTO может меняться со временем. Например, у DTO уже может быть флаг или что-то под названием IsBoth
, но с совершенно другим значением. В любом случае, просто предложение.
@Джулиан полностью согласен, лучше всего следовать шаблону mvvm
Я думал о специальном классе модели, например. SearchResult
, но это тоже работает.
вы не можете привязывать методы в XAML, только общедоступные свойства