Различные изображения для каждой ячейки FlowListView - PullRequest
0 голосов
/ 06 мая 2019

Итак, у меня есть FlowListView, и я хочу поместить разные изображения по умолчанию для каждой ячейки моего FlowListView, но я хочу поставить его через условие if, а условие if требует свойства Text моей кнопки. Я пытался сделать это в своем файле ViewModel и xaml.cs, но в ViewModel я не знаю, как получить свойство Text кнопок, и в моем файле xaml.cs я не знаю, как это сделать в конструкторе.

У меня есть

Я хочу это

Код Xaml:

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

CategoryDetailModel:

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

    }

Ответы [ 2 ]

1 голос
/ 06 мая 2019

Вы можете решить эту проблему несколькими способами:

  1. Вы можете создать ValueConverter, который преобразует ваш Id или Name в CategoryDetail в путь к изображению и привязывает его к свойству Image.
  2. Добавить изображение как свойство в CategoryDetail и напрямую связать

Для подхода ValueConveter вам необходимо реализовать интерфейс IValueConveter, он может выглядеть примерно так:

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также, если вы установите имена изображений позже.

0 голосов
/ 06 мая 2019

Ваши кнопки Команда привязана к IdCatalog, возможно, это числовое значение, это должно быть свойство ICommand, и ваша виртуальная машина должна выглядеть следующим образом:

public ICommand MyButtonCommand => new Command( (param) =>{ ... });
//Param is CommandParameter value, you should cast before use it

Если вы хотите использовать событие пользовательского интерфейса, сначала ваше свойство Image должно быть связано с вашей виртуальной машиной и установлено как свойство для уведомления.

Если вы измените изображение в качестве кода, пользовательский интерфейс не будет уведомлен об изменении значений.

РЕДАКТИРОВАНИЕ:

Ваш код с хорошей структурой должен быть таким

public partial class CategoriesMenuDetail : ContentPage
{
    public CategoriesMenuDetailViewModel ViewModel { get; set; }

    public CategoriesMenuDetail()
    {
        ViewModel = new CategoriesMenuDetailViewModel();

        InitializeComponent();

        BindingContext = Viewmodel;

    }
}


public class CategoriesMenuDetailViewModel 
{
    public List<CategoryDetail>MyCategories { get; set; } // if you don't add new items not need observable collection

    public ICommand ButtonClickedCommand => new Command((cParameter)=> ButtonclickedCommandExecute((CategoryDetail)cParameter)


    private void ButtonclickedCommandExecute(CategoryDetail myParam)
    {
        //Here goes you image's logic
        if (myParam.Name == "Carnes")
            myParam.ImageName = Image.FromFile("");
    }

}

public class CategoryDetail : ObservableObject
{
    public int Id { get; set; }
    private string _name;
    public string Name { get =>_name; set=>SetProperty(ref _name, value); }

    private string _imageName;
    public string  ImageName { get=>_imageName; set=>SetProperty(ref _imageName, value); }
}


public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    }

И XAML

 <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="{Binding ImageName}"
                                Command="{Binding ButtonClickedCommand}"
                                CommandParameter="{Binding .}"
                                TextColor="White"     
                                Clicked="ButtonSelected"                               
                                ContentLayout="Top"
                                BackgroundColor="#40000000"
                                BorderColor="#FFFFFF"
                                BorderWidth="2"
                                CornerRadius="6">
                    </Button>
                </DataTemplate>
            </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...