Как настроить стили ListBoxItem в UWP?

#uwp #uwp-xaml

Вопрос:

Мой Xaml:

     <ListBox x:Name="ListBox" Style="{StaticResource ListBoxStyle1}" Width="200" Height="200">
        
    </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="amp;#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>
 

И я привязал элемент DataTemplete, текстовый блок (ItemNameBlock), используя модель в .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;
     }
  } 
 

Вплоть до привязки имени, работает нормально.

У меня есть переключатель внутри DataTemplete , этот переключатель должен быть виден только для выбранного элемента.Как это сделать?

В то же время мне нужно изменить стиль ListBoxItem,такой как PointerOver,PointerPressed,SelectedPointerOver, используя VisualState!.Как это тоже сделать?

Ответ №1:

У меня есть переключатель внутри DataTemplete , этот переключатель должен быть виден только для выбранного элемента.Как это сделать?

Вы можете определить Visible свойство bool для класса модели для обработки видимого переключателя.

Например

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

Поле списка содержит SelectedItem свойство, которое можно использовать для получения выбранного элемента, обновления видимого свойства модели и записи предыдущего выбранного элемента. так что скройте 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>
 

В то же время мне нужно изменить стиль ListBoxItem,такой как PointerOver,PointerPressed,SelectedPointerOver, используя VisualState!.Как это тоже сделать?

Для этого вам нужно отредактировать ListBoxItem стиль по умолчанию. вы можете получить значение по умолчанию ListBoxItem в файле generic.xaml.

Комментарии:

1. Я сделал то, что ты сказал. Но видимость значка toogle Не изменится при изменении выбора. Пожалуйста,проверьте, Чего мне не хватает. Вот ссылка…. drive.google.com/drive/folders/…

2. Проблема в том, что ваш класс модели не инертен Model :INotifyPropertyChanged