Я хочу добиться эффекта, при котором ListBoxItem
выбирается (подсвечивается) на несколько секунд, а после этого отменяется. Попытка добиться простого выделения элемента управления с эффектами затухания, но для того, чтобы все заработало, мне нужно изменить свойство соответствующим образом.
У меня есть свойство IsSelected
, привязанное к моему свойству модели представления:
<Style TargetType = "{x:Type ListBoxItem}">
<Setter Property = "IsSelected" Value = "{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Style>
Моя собственность выглядит так:
public bool IsSelected
{
get => _isSelected;
set
{
// Update value
_isSelected = value;
// Raise property changed
OnPropertyChanged(nameof(IsSelected));
}
}
Я попытался использовать отложенную привязку:
<ControlTemplate TargetType = "{x:Type ListBoxItem}">
<ControlTemplate.Triggers>
<!-- Deselect after 5 seconds -->
<DataTrigger Binding = "{Binding IsSelected, Delay=5000}" Value = "True">
<Setter Property = "IsSelected" Value = "False" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Я также пробовал использовать раскадровки:
<ControlTemplate TargetType = "{x:Type ListBoxItem}">
<ControlTemplate.Triggers>
<!-- Deselect after 5 seconds -->
<DataTrigger Binding = "{Binding IsSelected}" Value = "True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty = "IsSelected">
<DiscreteBooleanKeyFrame KeyTime = "00:00:05" Value = "False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
К сожалению, ни один из вышеперечисленных подходов, похоже, не обновляет мое свойство IsSelected
, а ListBoxItem
остается выбранным и выделенным.
Я хочу, чтобы это было сделано в XAML (или расширениях), стиле MVVM, без кода и без расточительных таймеров - возможно ли это? Если да, то как правильно отменить выбор ListBoxItem
с задержкой?
@ mm8 Чтобы сделать его частью логики управления, потребуется создать по одному таймеру для каждого элемента управления. Одним из решений было бы поместить один таймер в модель представления списка, однако я уверен, что это не лучшее решение. Я думаю, что это можно сделать с помощью прикрепленных свойств (расширений разметки), что будет на 100% правильным решением, но пока у меня нет идей.
Прикрепленное поведение не «выполняется в XAML», поэтому вы можете немного перефразировать свой вопрос.
@ мм8 Верно. упомянул это в моем вопросе прямо сейчас.
Вот пример прикрепленного поведения, которое должно делать то, что вы хотите, более или менее:
public class DeselectBehavior
{
public static bool GetIsEnabled(ListBox listBox)
{
return (bool)listBox.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(ListBox listBox, bool value)
{
listBox.SetValue(IsEnabledProperty, value);
}
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached(
"IsEnabled",
typeof(bool),
typeof(DeselectBehavior),
new UIPropertyMetadata(false, OnChanged));
private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ListBox listBox = d as ListBox;
if ((bool)e.NewValue)
{
listBox.AddHandler(ListBoxItem.SelectedEvent, (RoutedEventHandler)OnListBoxItemSelected, true);
}
else
{
listBox.RemoveHandler(ListBoxItem.SelectedEvent, (RoutedEventHandler)OnListBoxItemSelected);
}
}
private static async void OnListBoxItemSelected(object sender, RoutedEventArgs e)
{
await Task.Delay(2000);
ListBoxItem listBoxItem = e.OriginalSource as ListBoxItem;
if (listBoxItem != null)
listBoxItem.IsSelected = false;
}
}
XAML:
<ListBox ... local:DeselectBehavior.IsEnabled = "True">
...
local:DeselectBehavior.IsEnabled = "True"
как я могу уведомить об использовании этого, что это можно использовать только для ListBox
. например, скажем, у меня есть еще один attached behavior
, который можно использовать только на кнопке. Затем, когда какой-то из них используется, это на чем-то еще, а дизайн как может их уведомить. или сделать компиляцию не удалось?
Почему вы хотите реализовать что-то подобное в XAML? Он должен быть частью логики управления, а XAML — это язык разметки. И что заставляет вас думать, что таймер более расточительный, чем
Storyboard
. Кажется, вы загнали себя в угол этими требованиями. MVVM, безусловно, не предназначен для устранения кода, связанного с представлением, и реализации поведения в XAML.