День добрый, был бы признателен, если бы подсказали как удалять кнопки и ставить на их место соседнюю по наступлению времени.
Исходное Допустим наступило 7 утра и вот такое желательно должно получиться
Честно, не уверен в данном примере, чисто мои наброски.
Хотел сделать так, что бы каждый элемент в коллекции был одним независимым объектом, который имеет свое время жизни. Естественно все по правилам MVVM.
И так, для начала нам нужен сам объект. Что в нем должно быть?
В итоге я сделал такой класс:
public class TimerViewModel : VM
{
public TimerViewModel(string name, TimeSpan time)
{
Name = name;
Time = time;
End = DateTime.Now.Add(Time);
StartTimer();
}
public string Name { get; set; }
public TimeSpan Time { get; set; }
public DateTime End { get; set; }
private TimeSpan _timeLeft;
public TimeSpan TimeLeft
{
get => _timeLeft;
set
{
_timeLeft = value;
OnPropertyChanged();
}
}
public event Action<TimerViewModel> Ended;
private DispatcherTimer _deleteTimer;
private DispatcherTimer _updateTimer;
private void StartTimer()
{
_deleteTimer = new DispatcherTimer();
_updateTimer = new DispatcherTimer();
_deleteTimer.Interval = End - DateTime.Now;
_updateTimer.Interval = TimeSpan.FromSeconds(1);
_deleteTimer.Tick += DeleteTimerOnTick;
_updateTimer.Tick += UpdateTimerOnTick;
_deleteTimer.Start();
_updateTimer.Start();
}
private void UpdateTimerOnTick(object sender, EventArgs e)
{
TimeLeft = End - DateTime.Now;
}
private void DeleteTimerOnTick(object sender, EventArgs e)
{
_deleteTimer.Stop();
_updateTimer.Stop();
Ended?.Invoke(this);
}
}
Данный класс наследует стандартный INotifyPropertyChanged (для отлавливание изменений в UI). Суть довольно проста:
Хорошо, у нас теперь есть VM объекта. Осталось сделать основную VM, заполнить ее и сделать View.
Основная ViewModel, что от нее требуется?
Ну что, попробуем:
public class MainViewModel : VM
{
public MainViewModel()
{
Timers = new ObservableCollection<TimerViewModel>();
Timers.CollectionChanged += TimersOnCollectionChanged;
Timers.Add(new TimerViewModel("Таймер 1", TimeSpan.FromSeconds(5)));
Timers.Add(new TimerViewModel("Таймер 2", TimeSpan.FromSeconds(10)));
Timers.Add(new TimerViewModel("Таймер 3", TimeSpan.FromSeconds(15)));
Timers.Add(new TimerViewModel("Таймер 4", TimeSpan.FromSeconds(20)));
Timers.Add(new TimerViewModel("Таймер 5", TimeSpan.FromSeconds(25)));
Timers.Add(new TimerViewModel("Таймер 6", TimeSpan.FromSeconds(30)));
Timers.Add(new TimerViewModel("Таймер 7", TimeSpan.FromSeconds(35)));
Timers.Add(new TimerViewModel("Таймер 8", TimeSpan.FromSeconds(35)));
Timers.Add(new TimerViewModel("Таймер 9", TimeSpan.FromMinutes(30)));
}
public ObservableCollection<TimerViewModel> Timers { get; set; }
private void TimersOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (TimerViewModel newItem in e.NewItems)
{
newItem.Ended += DeleteOldItemsEvent;
}
}
if (e.OldItems != null)
{
foreach (TimerViewModel newItem in e.OldItems)
{
newItem.Ended -= DeleteOldItemsEvent;
}
}
}
private void DeleteOldItemsEvent(TimerViewModel obj) => Timers.Remove(obj);
}
Что тут происходит:
Ну что, осталась View. Для такого вида, который хотите вы - стоит использовать WrapPanel, а из за того, что мы динамически создаем объекты - стоит использовать ItemsControl. Тут объяснять особо не буду, XAML в целом получился такой:
<ItemsControl ItemsSource="{Binding Timers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="Gray" BorderThickness="1" Width="70" Height="70" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Margin="3">
<TextBlock Text="{Binding Name}" FontWeight="Medium"/>
<TextBlock Text="{Binding TimeLeft, StringFormat=\{0:hh\\:mm\\:ss\}}"/>
</StackPanel>
<Border Grid.Row="1" Background="#FFDADADA" BorderBrush="Gray" BorderThickness="0,1,0,0">
<TextBlock Text="{Binding End, StringFormat=\{0:hh\\:mm\\:ss\}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Ну что, задаем DataContext и радуемся результатом:
По сути... Все это можно заменить на один таймер в MainViewModel, который будет раз в секунду тикать и к нему уже привязать основной таймер текущего времени, обновление и др. Я лишь показал один из возможных вариантов.
В общем удачи в программирование ;-)
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как добавить вывод имени, соответствующего максимальному значению?
Who can say me how to create same field like this in admin product pageAnd show in product card