В приложении по клику на разные кнопки меню в ContentControl подгружаются разные вьюшки. В каждой вьюьшке идет запрос к базе данных, каждую секунду в цикле, для обновления данных, получается что при переходе на другую вьюху, в предыдущей продолжает выполнятся метод, какое событие срабатывает при этом?
Это метод который каждую секунду срабатывает во ViewModel
CancellationTokenSource ct = null;
async void DBAsync()
{
while (true)
{
try
{
if (ct == null)
ct = new CancellationTokenSource();
}
catch (InvalidOperationException)
{
}
if (ct == null)
{
break;
}
try
{
await Task.Delay(TimeSpan.FromSeconds(3), ct.Token);
await Task.Run(() => getDataDB());
}
catch (OperationCanceledException)
{
}
}
}
В ContentControl
при изменении свойства Content
срабатывает метод OnContentChanged
, но к сожалению не существует стандартного события ContentChanged
, на которое можно было бы подписаться и узнавать таким образом об изменениях View внутри ContentControl
.
Но никто не мешает вам определить это событие самостоятельно:
public class CustomContentControl : ContentControl
{
public delegate void ContentChangeEventHandler(object sender, ContentChangedEventArgs e);
public static readonly RoutedEvent ContentChangedEvent
= EventManager.RegisterRoutedEvent(
nameof(ContentChanged),
RoutingStrategy.Bubble,
typeof(ContentChangeEventHandler),
typeof(CustomContentControl));
public event ContentChangeEventHandler ContentChanged
{
add => AddHandler(ContentChangedEvent, value);
remove => RemoveHandler(ContentChangedEvent, value);
}
protected override void OnContentChanged(object oldContent, object newContent)
{
var ea = new ContentChangedEventArgs(ContentChangedEvent, this) {NewContent = newContent};
RaiseEvent(ea);
base.OnContentChanged(oldContent, newContent);
}
}
public class ContentChangedEventArgs : RoutedEventArgs
{
public object NewContent { get; set; }
public ContentChangedEventArgs() : base() { }
public ContentChangedEventArgs(RoutedEvent routedEvent) : base(routedEvent) { }
public ContentChangedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }
}
Раз ваш метод выполняется в VM, ему не стоит знать о том, что есть во View. Ваш код должен по идее быть организован так:
ActivePart
, отвечающее за текущую активную «маленькую» VM, и список этих самых «маленьких» VM. Вызванная команда вызывает у активной маленькой VM метод Deactivate
, присваивает ActivePart
новую маленькой VM из списка, и вызывает у неё метод Activate
.
Activate
VM запускает метод наподобие DBAsync
, а в методе Deactivate
останавливает его. Для этого проще всего завести в маленькой VM поле bool flag
, цикл while (true)
поменять на while (flag)
, и при необходимости оборвать цикл просто устанавливать flag = false;
.Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как сделать sprite во весь экран (Независимую размерность, унив?
Помогите написать на любом языке программу, которая
Это код игры в WindowsFormПри открытии игра сразу начинает работать но нужно что бы было по нажатию ENTER, как это сделать это я не понял