<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Grid.Row="0" Grid.Column="0" Command="{Binding ClickCmd}" Content="Click Cmd"/> <Button Grid.Row="0" Grid.Column="1" Command="{Binding CancelCmd}" Content="Cancel Cmd"/> <ListBox Grid.Row="1" BorderBrush="Black" BorderThickness="3" Grid.RowSpan="2" ItemsSource="{Binding ContentOb,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace WpfApplication1.Model { public class DelegateCommand : ICommand { private readonly Predicate<object> _canExecute; private readonly Action<object> _execute; public event EventHandler CanExecuteChanged; public DelegateCommand(Action<object> execute) : this(execute, null) { } public DelegateCommand(Action<object> execute, Predicate<object> canExecute) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { if (_canExecute == null) { return true; } return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) { CanExecuteChanged(this, EventArgs.Empty); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel; using WpfApplication1.Model; using System.Collections.ObjectModel; using System.Threading; using System.Windows; using System.IO; using Newtonsoft.Json; namespace WpfApplication1.ViewModel { public class WpfVM : INotifyPropertyChanged { private WpfVM() { } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private static WpfVM Wpfvm; private static readonly object objLock = new object(); public static WpfVM GetWpfVM() { lock(objLock) { if(Wpfvm == null) { Wpfvm = new WpfVM(); } return Wpfvm; } } private static CancellationTokenSource cts=new CancellationTokenSource(); #region Commands private DelegateCommand ClickCmdValue; public DelegateCommand ClickCmd { get { if(ClickCmdValue==null) { ClickCmdValue = new DelegateCommand(ClickCmdExecuted); } return ClickCmdValue; } } private string ContentValue; public string Content { get { return ContentValue; } set { if(value!=ContentValue) { ContentValue = value; OnPropertyChanged("Content"); } } } private bool IsCancelledValue=false; public bool IsCancelled { get { return IsCancelledValue; } set { if(value!=IsCancelledValue) { IsCancelledValue = value; OnPropertyChanged("IsCancelled"); } } } private void ClickCmdExecuted(object obj) { ContentOb = new ObservableCollection<string>(); Task.Run(() => { while (!cts.IsCancellationRequested) { Content = DateTime.Now.ToString("yyyyMMddHHmmssffff"); App.Current.Dispatcher.BeginInvoke((Action)delegate { ContentOb.Add(Content); }); System.Diagnostics.Debug.WriteLine(Content); } },cts.Token); } private DelegateCommand CancelCmdValue; public DelegateCommand CancelCmd { get { if(CancelCmdValue==null) { CancelCmdValue = new DelegateCommand(CancelCmdValueExecuted); } return CancelCmdValue; } } private void CancelCmdValueExecuted(object obj) { cts.Cancel(); IsCancelled = true; System.Diagnostics.Debug.WriteLine("Cancelled!"); string msJsonSerializerString = JsonConvert.SerializeObject(ContentOb,Formatting.Indented); string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".txt"; using(StreamWriter streamWriter=new StreamWriter(fileName,true,Encoding.UTF8)) { streamWriter.WriteLine(msJsonSerializerString); } } #endregion #region Properties private ObservableCollection<string> ContentObValue; public ObservableCollection<string> ContentOb { get { return ContentObValue; } set { if(value!=ContentObValue) { ContentObValue = value; OnPropertyChanged("ContentOb"); } } } #endregion } }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 using WpfApplication1.ViewModel; 16 17 namespace WpfApplication1 18 { 19 /// <summary> 20 /// Interaction logic for MainWindow.xaml 21 /// </summary> 22 public partial class MainWindow : Window 23 { 24 public MainWindow() 25 { 26 InitializeComponent(); 27 WpfVM vm = WpfVM.GetWpfVM(); 28 this.DataContext = vm; 29 } 30 } 31 }
private void ClickCmdExecuted(object obj)
{
ContentOb = new ObservableCollection<string>();
Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
Content = DateTime.Now.ToString("yyyyMMddHHmmssffff");
App.Current.Dispatcher.BeginInvoke((Action)delegate
{
ContentOb.Add(Content);
});
System.Diagnostics.Debug.WriteLine(Content);
}
},cts.Token);
}