PremKumar Shanmugam
PremKumar Shanmugam

Reputation: 441

How to customize styles of listBoxItem in UWP?

My Xaml:

    <ListBox x:Name="ListBox" Style="{StaticResource ListBoxStyle1}" Width="200" Height="200">
        
    </ListBox>

I have a custom ItemTemplete for ListBox.

    <Style x:Key="ListBoxStyle1" TargetType="ListBox">
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"/>
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="BorderThickness" Value="{ThemeResource ListBoxBorderThemeThickness}"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
        <Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="True"/>
        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/>
        <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
        <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
        <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
        <Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="TabNavigation" Value="Once"/>
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
        <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <RelativePanel x:Name="Holder">
                        <FontIcon x:Name="ToogleIcon" FontFamily="Segoe MDL2 Assets" Width="18" Height="12" Glyph="&#xE73E;"/>
                        <TextBlock x:Name="ItemNameBlock" Margin="23 0 0 0" Text="{Binding Name}"/>
                    </RelativePanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                        <ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
                            <ItemsPresenter/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

And i have bind the DataTemplete element, TextBlock (ItemNameBlock) using Model in .cs.

class Model
{
    public Model(string name)
    {
        this.Name = name;
    }
    public string Name { get; set; }
}

 Class Load
 {
    publc void LoadData()
    {  
       Model model = new Model("Hai");
        Model model1 = new Model("Hello");
        ObservableCollection<Model> observable = new ObservableCollection<Model>();
        observable.Add(model);
        observable.Add(model1);
        ListBox.ItemsSource = observable;
     }
  } 

Upto binding the Name, works fine.

I have ToggleIcon inside the DataTemplete , that toggleIcon must be visible only for the selectedItem.How to do that?

At the same time,I need to change the ListBoxItem style like PointerOver,PointerPressed,SelectedPointerOver using visualState!.How to do this also?

Upvotes: 0

Views: 237

Answers (1)

Nico Zhu
Nico Zhu

Reputation: 32785

I have ToggleIcon inside the DataTemplete , that toggleIcon must be visible only for the selectedItem.How to do that?

You could define bool Visible property for the Model class to handle ToggleIcon visible.

For example

public class Model : INotifyPropertyChanged
{
    public Model(string name)
    {
        this.Name = name;
    }
    public string Name { get; set; }
    private bool _visible;
    public bool Visible
    {

        get => _visible;
        set
        {
            _visible = value;
            NotifyPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            // PropertyChanged is always null.
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ListBox contains SelectedItem property, you could use it to get selected item, and update model Visible property, and record previous selected item. so that hide the ToggleIcon of previous item when select the next one.

public sealed partial class MainPage : INotifyPropertyChanged
{
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
    }


    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            // PropertyChanged is always null.
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private Model _selectItem;
    private Model _privousItem;
    public Model SelectItem
    {
        get => _selectItem;
        set
        {
            if (_privousItem != null)
            {
                _privousItem.Visible = false;
            }

            _selectItem = value;

            NotifyPropertyChanged();
            _selectItem.Visible = true;
            _privousItem = _selectItem;
        }
    }


    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        MyList.ItemsSource = new ObservableCollection<Model> {
        new Model("hello"),
          new Model("hello1"),
            new Model("hello2"),
              new Model("hello3"),
                new Model("hello4"),
                  new Model("hello5"),
                    new Model("hello6"),
        };
    }

}

Xaml code

<ListBox x:Name="MyList" SelectedItem="{Binding SelectItem, Mode=TwoWay}">

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <SymbolIcon
                    x:Name="MySbl"
                    HorizontalAlignment="Right"
                    Symbol="Accept"
                    Visibility="{Binding Visible}" />
            </StackPanel>

        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

At the same time,I need to change the ListBoxItem style like PointerOver,PointerPressed,SelectedPointerOver using visualState!.How to do this also?

For doing this you need edit the default ListBoxItem style. you could get the default ListBoxItem in the generic.xaml file.

Upvotes: 1

Related Questions