Необходимо изменить состояние кнопки ("Старт/Стоп") и запустить одновременно этой кнопкой сервис(в моем случае скриншот с вебкамеры). Пытаюсь сделать таким образом:
public MainWindowViewModel()
{
InitializeServices();
InitializeCommands();
}
private void ToggleWebServiceExecute()
{
//_isRunning = !_isRunning;
//v_Button_ToggleWebCam.Content = _isRunning ? "Stop" : "Start";
if (!_faceDetectionService.IsRunning)
{
_cameraDetectionService.RunServiceAsync();
}
else
{
_cameraDetectionService.CancelServiceAsync();
}
}
<Button Name="v_Button_ToggleWebCam" Grid.Row="1" Command="{Binding ToggleWebServiceCommand}"
VerticalAlignment="Center" Content="{Binding ButtonText}"
Класс ViewModel:
#region ButtonContent
private ICommand _StartCommand;
private ICommand _StopCommand;
private string _buttonText;
public string ButtonText
{
get { return _buttonText ?? (_buttonText = "Start"); }
set
{
// From INotifyPropertyChanged
//SetField(ref _buttonText, value);
NotifyPropertyChanged("ButtonText");
}
}
private ICommand _buttonClickCommand;
public ICommand ButtonClickCommand
{
get { return _buttonClickCommand ?? (_buttonClickCommand = _StartCommand); }
set
{
_buttonClickCommand = value;
//SetField(ref _buttonClickCommand, value);
NotifyPropertyChanged("ButtonClickCommand");
}
}
private void Stop()
{
ButtonText = "Stop";
ButtonClickCommand = _StopCommand;
}
private void Start()
{
ButtonText = "Start";
ButtonClickCommand = _StartCommand;
}
#endregion
Команда на этой же кнопке для запуска сервиса:
private ICommand _toggleWebServiceCommand;
public ICommand ToggleWebServiceCommand
{
get
{
return _toggleWebServiceCommand;
}
private set { }
}
Инициализация команд:
private void InitializeCommands()
{
_toggleWebServiceCommand = new DelegateCommand(ToggleWebServiceExecute);
_StartCommand = new DelegateCommand(Stop);
_StopCommand = new DelegateCommand(Start);
}
Класс команды
public class DelegateCommand : ICommand
{
private readonly Action _command;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public DelegateCommand(Action command, Func<bool> canExecute = null)
{
if (command == null)
throw new ArgumentNullException();
_canExecute = canExecute;
_command = command;
}
public void Execute(object parameter)
{
_command();
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
}
XAML
<Canvas>
<Button Command="{Binding StartStopCommand, Mode=OneTime}"
Canvas.Left="183"
Canvas.Top="222"
Width="75">
<Button.Content>
<TextBlock Text="{Binding ButtonContent}" />
</Button.Content>
</Button>
<ProgressBar Height="20"
Minimum="0"
Maximum="100"
Value="{Binding ProgressShow}"
Canvas.Left="77"
Canvas.Top="108"
Width="299" />
</Canvas>
вьюмодель (немного переделал код под ваш случай пример ответа из вопроса про запуск неблокирующей UI задачи)
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
//источник токена отмены
private CancellationTokenSource _tokenSource;
//ctor
public MainViewModel()
{
}
/// <summary>
/// Надпись на кнопке
/// </summary>
private string _ButtonContent;
public string ButtonContent
{
get => _ButtonContent;
set
{
_ButtonContent = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonContent)));
}
}
/// <summary>
/// Для отображения в ProgressBar
/// </summary>
private int _ProgressShow;
public int ProgressShow
{
get => _ProgressShow;
set
{
_ProgressShow = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProgressShow)));
}
}
/// <summary>
/// Флаг работы долгой задачи
/// </summary>
private bool _IsRunning;
public bool IsRunning
{
get => _IsRunning;
set
{
_IsRunning = value;
//обновление кнопки
StartStopCommand.RaiseCanExecuteChanged();
}
}
/// <summary>
/// Кнопка запуска и останова
/// </summary>
private RelayCommand _StartStopCommand;
public RelayCommand StartStopCommand
{
get => _StartStopCommand = _StartStopCommand ?? new RelayCommand(OnStartStop, CanStartStop);
}
private bool CanStartStop()
{
if (IsRunning)
{
ButtonContent = "Стоп";
}
else
{
ButtonContent = "Старт";
}
return true;
}
private async void OnStartStop()
{
//проверяем а была ли запущена задача
if (IsRunning)
{
//останавливаем задачу
_tokenSource.Cancel();
//
IsRunning = false;
return;
}
//--иначе запускаем задачу
//кнопки
IsRunning = true;
// через него будем оповещать о ходе выполнения задачи
Progress<int> progress = new Progress<int>(n => ProgressShow = n);
//готовим токен отмены
_tokenSource = new CancellationTokenSource();
CancellationToken cancelToken = _tokenSource.Token;
try
{
// ВНИМАНИЕ! Вот запуск нашего долгого метода
// обратите внимание на передачу параметров
// токен отмены мы должны передать и в целевой метод
// и собственно в метод Run()
await Task.Run(() => DoIteration(cancelToken, progress), cancelToken);
}
catch (OperationCanceledException)
{
//случай отмены
ProgressShow = 0;
}
catch (Exception)
{
//случай если возникнет какая-то ошибка
Debug.WriteLine("-->Error");
ProgressShow = 0;
}
finally
{
// кнопки
IsRunning = false;
// удаляем источник токена отмены
_tokenSource.Dispose();
}
}
// Это наш долгий метод, который сообщает о ходе своего выполнения
// и может быть отменен в любой нужный момент
// обратите внимание на второй параметр IProgress<int> progress
// здесь должен быть обязательно интерфейс,
// если случайно нашите Progress<int>, то не найдете Report()
private void DoIteration(CancellationToken cancelToken, IProgress<int> progress)
{
//создаем экземпляр нашего подсобного класса
Iteration iteration = new Iteration();
// типа какая-то полезная работа
foreach (int number in iteration.StartIterator())
{
//отображаем ход работы метода
progress.Report(number);
//выбрасываем исключение в случае нажатия на кнопку отмены
cancelToken.ThrowIfCancellationRequested();
}
}
}
Класс команд (писал не сам, пару лет назад взял из одного проекта, и теперь этот класс кочует у меня из проекта в проект)
public class RelayCommand : ICommand
{
Action _targetExecuteMethod;
Func<bool> _targetCanExecuteMethod;
public RelayCommand(Action executeMethod)
{
_targetExecuteMethod = executeMethod;
}
public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
{
_targetExecuteMethod = executeMethod;
_targetCanExecuteMethod = canExecuteMethod;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members
bool ICommand.CanExecute(object parameter)
{
if (_targetCanExecuteMethod != null)
{
return _targetCanExecuteMethod();
}
if (_targetExecuteMethod != null)
{
return true;
}
return false;
}
// Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
// Prism commands solve this in their implementation
public event EventHandler CanExecuteChanged = delegate { };
void ICommand.Execute(object parameter)
{
if (_targetExecuteMethod != null)
{
_targetExecuteMethod();
}
}
#endregion
}
public class RelayCommand<T> : ICommand
{
Action<T> _targetExecuteMethod;
Func<T, bool> _targetCanExecuteMethod;
public RelayCommand(Action<T> executeMethod)
{
_targetExecuteMethod = executeMethod;
}
public RelayCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod)
{
_targetExecuteMethod = executeMethod;
_targetCanExecuteMethod = canExecuteMethod;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members
bool ICommand.CanExecute(object parameter)
{
if (_targetCanExecuteMethod != null)
{
T tparm = (T)parameter;
return _targetCanExecuteMethod(tparm);
}
if (_targetExecuteMethod != null)
{
return true;
}
return false;
}
// Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
// Prism commands solve this in their implementation
public event EventHandler CanExecuteChanged = delegate { };
void ICommand.Execute(object parameter)
{
if (_targetExecuteMethod != null)
{
_targetExecuteMethod((T)parameter);
}
}
#endregion
}
Требуется открыть в браузере две страницыК примеру, программа открывает YouTube
Все мучаюсь над чтением и записью больших exe файлов, нужно чтоб программа читала большой exe файл и меняла в нем некоторые символы после чего...
Есть программа на winformsС помощью codefirst создана таблица