Wpf Dispatcher.BeginInvoke((Action)delegate{}));
<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);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2016-11-27 WPF 页面导航