0
I have a CollectionView<T> with 2 columns.  
The SelectionMode=Single.  
Problem :    
  The second column displays only a few colors names, 
  not all and after a selection no more color names !

I use Visual Studio 2022 17.11.5 Maui Android C#.
I haven't found a solution to this problem for a few days now.
Files xaml and code and display are below. The binding for ColorValue and ColorName are the same although the colors display well but not the names of these colors !

Do someone can explain me what fault I do, please ? Thank you

.

File PickColorPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:helpers="clr-namespace:Helpers"
             xmlns:vm="clr-namespace:ViewsViewModels"
             BackgroundColor="White"
             x:Class="ViewsViewModels.PickColorPage"
             x:Name="PickColorPageName"
             Title="Help">
    <Shell.BackButtonBehavior>
        <BackButtonBehavior IsVisible="False"/>
    </Shell.BackButtonBehavior>
    <Shell.TitleView>
        <Grid ColumnDefinitions="*">
            <Label Text="{Binding Title, Source={x:Reference PickColorPageName}}" HorizontalOptions="Center" VerticalOptions="Center" FontSize="32" FontAttributes="Bold"/>
        </Grid>
    </Shell.TitleView>
    <ContentPage.Resources>
        <ResourceDictionary>
            <helpers:ColorToRGBConverter x:Key="ColorToRGBConverter"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid RowDefinitions="auto,*,auto">
        <Label Text="{Binding Setting.SettingDescription, Source={x:Reference PickColorPageName}}"
               BackgroundColor="LightCyan" TextDecorations="Underline" FontSize="16" FontAttributes="Bold" HorizontalOptions="CenterAndExpand"/>
        <CollectionView x:Name="cv" Grid.Row="1" ItemsSource="{Binding ListOfColors, Source={x:Reference PickColorPageName}}" Loaded="cv_Loaded" 
                        ItemSizingStrategy="MeasureFirstItem" SelectionMode="Single" SelectionChanged="cv_SelectionChanged">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid ColumnDefinitions="auto,*">
                        <Border Grid.Column="0" StrokeShape="RoundRectangle 10,0,0,10" StrokeThickness="1" Stroke="Red" WidthRequest="180" BackgroundColor="Beige">
                            <BoxView Color="{Binding ColorValue, Converter={StaticResource ColorToRGBConverter}}"
                                     CornerRadius = "10" HeightRequest = "32" WidthRequest="120" HorizontalOptions="CenterAndExpand" Margin="10"/>
                        </Border>
                        <Label Grid.Column="1" Text="{Binding ColorName}" VerticalOptions="Center" FontSize="20" FontAttributes="Bold" Margin="10" HorizontalTextAlignment="Start"/>
                   </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Grid Grid.Row="2" ColumnDefinitions="*,*" BackgroundColor="LightYellow" VerticalOptions="End" HorizontalOptions="FillAndExpand" x:DataType="vm:MainViewModel">
            <Button Grid.Column="0" Text="Save" Margin="20,4" Padding="20,0" FontSize="20" Command="{Binding SaveSettingsCommand}"/>
            <Button Grid.Column="1" Text="Cancel" Margin="20,4" Padding="20,0" FontSize="20" Clicked="Cancel"/>
        </Grid>
    </Grid>
</ContentPage>

File PickColorPage.xaml.cs

using System.Collections.ObjectModel;
using Models;

namespace ViewsViewModels
{
    public partial class PickColorPage : ContentPage, IQueryAttributable, INotifyPropertyChanged
    {
        public Setting Setting { get; set; }
        public Setting StartSetting { get; set; }

        void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query)
        {
            if (query.Values.Count == 0) return;
            Setting = query.Values.ElementAt(0) as Setting;
            StartSetting = new Setting(Setting);
            OnPropertyChanged(nameof(Setting));
            InitColorsList();
            System.Diagnostics.Debug.WriteLine($"**************** ListofColors => {ListOfColors.Count}");
//            int i = 0; foreach (ClColor c in ListOfColors) { i++; System.Diagnostics.Debug.WriteLine($"{i} => {c.ColorName}"); }
        }

        public ObservableCollection<ClColor> ListOfColors { get; } = [];

        public PickColorPage(MainViewModel vm)
        {
            InitializeComponent();
            BindingContext = vm;
       }

        public partial class ClColor : ObservableObject
        {
            [ObservableProperty]
            public string colorName;
            [ObservableProperty]
            public string colorValue;

            public ClColor(string _colorName, string _colorValue)
            { 
                ColorName= _colorName;
                ColorValue= _colorValue;
            }
        }

        public void InitColorsList()
        {
            System.Drawing.Color c;
            List<string> ls = GetListOfColors();
            ListOfColors.Clear();
            foreach (string s in ls)
            {
                c = System.Drawing.Color.FromName(s);
                string chex = ToHexString(c);
                string settingColor = (string)Setting.SettingValue;
                bool rdbtn = chex.Equals(settingColor, StringComparison.InvariantCultureIgnoreCase);
                ListOfColors.Add(new ClColor(s, chex));
            }
//            int i = 0; foreach(ClColor r in ListOfColors) { Console.WriteLine($"{i} => {r.RdbtnChecked}"); i++; }
       }

        private static string ToHexString(System.Drawing.Color color)
        {
            byte r = color.R;
            byte g = color.G;
            byte b = color.B;
            //        byte a = color.A;
            //        return string.Format("#{0,2:X2}{1,2:X2}{2,2:X2}{3,2:X2}", r, g, b, a);
            return string.Format("#{0,2:X2}{1,2:X2}{2,2:X2}", r, g, b);
        }

        public static List<string> GetListOfColors()
        {
            List<string> colorList = [];

            // Get type of KnownColor enum
            var color = typeof(System.Drawing.KnownColor);

            // Enumerate all known color names in enum
            var colors = Enum.GetValues(color);

            // Remove 27 elements from beginning & 7 elements from the end (windows controls)
            var from = 26;
            var to = colors.Length - 8;

            // Only keep color names and not user interface colors
            for (int i = from; i < to; i++) colorList.Add(colors.GetValue(i).ToString());

            // Return filtered color list
            return colorList;
        }


        private async void cv_Loaded(object sender, EventArgs e)
        {
            await Task.Delay(1000);  // it seems a bug exists in ScrollTo(), hence this delay to PARTIALLY solve this problem
            ClColor clc = ListOfColors.FirstOrDefault(predicate: cl => cl.ColorValue == (string)Setting.SettingValue);
            cv.ScrollTo(clc, group:null, position: ScrollToPosition.Center, animate: false); // false because scroll does work very badly !!!
            cv.SelectedItem = clc;
        }

        ClColor? previousSelection = null;

        private void cv_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            previousSelection = e.PreviousSelection.FirstOrDefault() as ClColor;
            ClColor? x = e.CurrentSelection.FirstOrDefault() as ClColor;
            Setting.SettingValue = x.ColorValue;
        }

        public void Cancel(object sender, EventArgs e)
        {
            Setting.SettingValue = StartSetting.SettingValue;
            OnPropertyChanged(nameof(Setting));
            Shell.Current.GoToAsync(".."); 
        }
    }
}

File ConfigModels.cs

using CommunityToolkit.Mvvm.ComponentModel;

namespace Models
{
    public class Setting : ObservableObject
    {
        public Setting() { SettingDescription = ""; SettingType = null; SettingValue = Colors.White; }
        public Setting(Setting s) { SettingDescription = s.SettingDescription; SettingType = s.SettingType; SettingValue = s.SettingValue; }
        public Setting(string desc, Type type, object val) { SettingDescription = desc; SettingType = type; SettingValue = val; }

        private string settingDescription;
        public string SettingDescription
        {
            get { return settingDescription; }
            set { SetProperty(ref settingDescription, value); }
        }

        private Type? settingType;  // color or double
        public Type SettingType
        {
            get => settingType;
            set { SetProperty(ref settingType, value); }
        }

        private object settingValue;
        public object SettingValue
        {
            get { return settingValue; }
            set { SetProperty(ref settingValue, value); }
        }
    }
8
  • I can't create a sample to reproduce the problem because you didn't provide the code about the viewmodel and the converter. And I can't under your first problem clearly. Commented Oct 29, 2024 at 2:00
  • I have edited my question and added files. Commented Oct 29, 2024 at 23:00
  • Still missed the class about the MainViewModel and the ColorConverter. In addition, did you know the ColorTypeConverter can convert the colorname to color directly? Commented Oct 30, 2024 at 5:53
  • And there were some stranged errors when I copied your code. So a smallest sample that can reproduce this problem is a better way. Commented Oct 30, 2024 at 6:01
  • It's difficult to put a smallest sample because of the sizes of the code I would set. Commented Nov 1, 2024 at 15:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.