如何在UWP中自定义listBoxItem的样式?

How to customize styles of listBoxItem in UWP?

我的Xaml:

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

我有一个用于 ListBox 的自定义 ItemTemplete。

    <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>

并且我已经使用 .cs 中的模型绑定了 DataTemplete 元素 TextBlock (ItemNameBlock)。

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

直到绑定名称,工作正常。

我在 DataTemplete 中有 ToggleIcon,toggleIcon 必须只对 selectedItem.How 可见吗?

同时,我需要使用 visualState 更改 ListBoxItem 样式,如 PointerOver、PointerPressed、SelectedPointerOver!。这也该怎么做?

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

您可以为模型 class 定义 bool Visible 属性 来处理可见的 ToggleIcon。

例如

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 包含 SelectedItem 属性,您可以使用它来获取 selected 项,并更新模型可见 属性,并记录上一个 select编项目。以便在 select 下一个项目时隐藏上一个项目的 ToggleIcon

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代码

<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?

为此,您需要编辑默认的 ListBoxItem 样式。您可以在 generic.xaml 文件中获得默认值 ListBoxItem