#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