본문 바로가기
프로그래밍/App 개발

[Xamarin] CollectionView Selected Item Color

by 엽기토기 2020. 11. 24.
반응형


방법 1. Trigger 사용 (버그 존재)

var triggerTrue = new DataTrigger(typeof(CollectionCellLayout))
{
       Value = true,
       Binding = new Binding() { Path = "IsChecked" }
};

var setterTrue = new Setter
{
       Property = BackgroundColorProperty,
       Value = Color.FromRgb(247, 247, 249)
};

triggerTrue.Setters.Clear();
triggerTrue.Setters.Add(setterTrue);
this.Triggers.Add(triggerTrue);

이런 식으로 하면, 터치를 뗐을 때 설정한 색상으로 변경한다.

하지만 터치를 한 순간 (아직 안뗌)의 색상은 바뀌지않는다.

터치를 한 순간부터 떼기까지의 색상을 동일하게 하고 싶은데...

방법 2. Style and VisualState 사용

Style을 사용하면 된다.

VisualState Normal과 Selected를 설정해준다.

(1) Xamarin.Forms View (Grid or StackLayout ...)

App.xaml

<ResourceDictionary>
       <Style TargetType="Grid">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        
                        <VisualState x:Name="Normal">
                          <VisualState.Setters>
                                <Setter Property="BackgroundColor"
                                        Value="White" />
                                 </VisualState.Setters>
                        </VisualState>

                        <VisualState x:Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="VisualElement.BackgroundColor"
                                        Value="#f7f7f9" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
        </ResourceDictionary>

(2) Custom Layout

📌 Property를 VisualElement.BackgroundColor로 설정해야 함.

namespace와 assembly를 custom layout의 위치로 설정 후, Style의 TargetType을 해당 이름으로 설정.

App.xaml

<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NathanPicker.App"
     xmlns:local="clr-namespace:NathanPicker;assembly=NathanPicker">
<ResourceDictionary>
       <Style TargetType="{x:Type local:CollectionCellLayout}">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        
                        <VisualState x:Name="Normal">
                          <VisualState.Setters>
                                <Setter Property="VisualElement.BackgroundColor"
                                        Value="White" />
                                 </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="VisualElement.BackgroundColor"
                                        Value="#f7f7f9" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
        </ResourceDictionary>

xaml 대신 C# 코드로도 설정 할 수 있다.

중복 코드는 함수 Setter SetSetter(Color normalColor, Color selectedColor)로 작성하였음.

using Xamarin.Forms;
using Dreamfora;

namespace NathanPicker
{
    public partial class App : Application
    {
        public App()
        {
            var iconCollectionCellStyle = new Style(typeof(CollectionCellLayout))
            {
                Setters =
                {
                   SetSetter(Color.White, Color.FromHex("#f7f7f9"))
                }
            };

            var nonIconCollectionCellStyle = new Style(typeof(NonIconCollectionCellLayout))
            {
                Setters =
                {
                   SetSetter(Color.FromHex("#f7f7f9"), Color.FromHex("#f7f7f9"))
                }
            };

            var resourceDictionary = new ResourceDictionary();
            resourceDictionary.Add(iconCollectionCellStyle);
            resourceDictionary.Add(nonIconCollectionCellStyle);

            Resources = resourceDictionary;

            
            MainPage = DFMainPage.Instance;
        }

        private Setter SetSetter(Color normalColor, Color selectedColor)
        {
            var visualStateGroup = new VisualStateGroup
            {
                Name = "CommonStates",
                States =
                {
                    new VisualState
                    {
                        Name= "Normal",
                        Setters =
                        {
                            new Setter
                            {
                                Property = VisualElement.BackgroundColorProperty,
                                Value = normalColor
                            }
                        }
                    },
                    new VisualState
                    {
                        Name= "Selected",
                        Setters =
                        {
                            new Setter
                            {
                                Property = VisualElement.BackgroundColorProperty,
                                Value = selectedColor
                            }
                        }
                    }
                }
            };

            var visualStateGroupList = new VisualStateGroupList();
            visualStateGroupList.Add(visualStateGroup);

            return new Setter
            {
                Property = VisualStateManager.VisualStateGroupsProperty,
                Value = visualStateGroupList
            };
        }


        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
    }
}


반응형