c# - 每个 FlowListView 单元格的不同图像
问题描述
所以我有一个 FlowListView,我想为我的 FlowListView 的每个单元格放置与默认值不同的图像,但我想通过一个 if 条件来放置它,并且 if 条件需要我的按钮的 Text 属性。我尝试在 ViewModel 和 xaml.cs 文件中执行此操作,但在 ViewModel 中我不知道如何获取按钮的 Text 属性,并且在我的 xaml.cs 文件中我不知道如何在构造函数中执行此操作。
Xml代码:
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="Default" HasUnevenRows="true" FlowColumnExpand="ProportionalLast"
FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}"
FlowItemsSource="{Binding MyCategories}" >
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Button Text="{Binding Name}"
Image="carne.png"
Command="{Binding IdCatalogs}"
CommandParameter="{Binding Id}"
TextColor="White"
Clicked="ButtonSelected"
ContentLayout="Top"
BackgroundColor="#40000000"
BorderColor="#FFFFFF"
BorderWidth="2"
CornerRadius="6">
</Button>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
Xaml.cs 文件代码:
public partial class CategoriesMenuDetail : ContentPage
{
public Dictionary<int, Btn> buttons { get; set; }
public CategoriesMenuDetail()
{
InitializeComponent();
buttons = new Dictionary<int, Btn>();
}
public void ButtonSelected(object sender, EventArgs e)
{
var button = (Button)sender;
if (!buttons.ContainsKey(button.GetHashCode()))
{
buttons.Add(button.GetHashCode(), new Btn(button));
}
bool state = buttons[button.GetHashCode()].Toogle();
if (button.Text == "Carnes")
{
var image = (state) ? "carneslc.png" : "carne.png";
button.Image = image;
}
if (button.Text == "Peixes")
{
var image = (state) ? "peixeslc.png" : "peixe.png";
button.Image = image;
}
if (button.Text == "Entradas")
{
var image = (state) ? "entradaslc.png" : "entrada.png";
button.Image = image;
}
var bgColor = (state) ? Color.FromHex("#26047AD5") : Color.FromHex("#40000000");
var borderColor = (state) ? Color.FromHex("#FF8A00") : Color.FromHex("#FFFFFF");
button.BackgroundColor = bgColor;
button.BorderColor = borderColor;
}
}
public class Btn
{
private Button _button { get; set; }
private bool isToogle = false;
public Btn(Button button)
{
_button = button;
}
public bool Toogle()
{
isToogle = !isToogle;
return isToogle;
}
}
视图模型代码:
private RestaurantsClient restaurantsClient { get; set; }
private ObservableCollection<CategoryDetail> _myCategories;
public ObservableCollection<CategoryDetail> MyCategories
{
set
{
_myCategories = value;
NotifyPropertyChanged(nameof(MyCategories));
}
get
{
return _myCategories;
}
}
public RestaurantsReaderViewModel()
{
restaurantsClient = (App.Current as App).restaurantsClient;
var restaurantsNames = restaurantsClient.GetCategoriesAsync(2).Result;
MyCategories = new ObservableCollection<CategoryDetail>(restaurantsNames.Categories);
}
类别详细型号:
public partial class CategoryDetail
{
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
public int Id { get; set; }
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Name { get; set; }
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
public static CategoryDetail FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<CategoryDetail>(data);
}
}
解决方案
您可以通过几种不同的方式解决此问题:
- 您可以创建一个 ValueConverter,它将 CategoryDetail 上的 Id 或 Name 转换为图像路径并将其绑定到
Image
属性。 - 在 CategoryDetail 中添加图片作为属性,直接绑定
对于您需要实现IValueConveter
接口的 ValueConveter 方法,它可能如下所示:
public class CategoryImageValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var name = (string)value;
switch (name)
{
case "Entradas":
return "entradas.png";
case "Carnes":
return "carnes.png";
case "Peixes":
return "peixes.png";
// add more here
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后你需要告诉 Xamarin.Forms 在哪里寻找这个 ValueConverter。所以在页面上添加:
<ContentPage.Resources>
<ResourceDictionary>
<local:CategoryImageValueConverter x:Key="categoryImage" />
</ResourceDictionary>
</ContentPage.Resources>
现在您可以将Image
属性的绑定更改为:
Image="{Binding Name, Converter{StaticResource categoryImage}}"
至于将其直接放入 CategoryDetail 类的其他解决方案,您只需创建一个新属性并使用正确的图像名称填充这些项目并绑定该属性。例如,让我们称之为ImageName
:
Image="{Binding ImageName}"
在 CategoryDetail 中它看起来像这样:
private string _imageName;
public string ImageName
{
get => _imageName;
set
{
_imageName = value;
}
}
如果您的 CategoryDetail 类实现了 INotifyPropertyChanged,请记住在稍后设置图像名称时也触发 PropertyChanged 事件。