[英]Update textbox in realtime in wpf giving no error with no output
在嘗試制作基於GUI的簡單秒表時,我嘗試了多種方法來使其實時更新。 trying to make it look pretty at all, I am just trying to get the program to run. 截至目前,我並試圖使它看起來很漂亮,我只是想讓程序運行。 我已經包含了我嘗試使用的方法來更新TextBlock
。 我嘗試的最后一個方法是this.Dispatcher.Invoke( new Action(() => ...
方法。我嘗試的另一種方法是使用async-await
方法,該方法已包含在注釋中的代碼中)。
namespace WpfApp3
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private /*async*/ void start_Click(object sender, RoutedEventArgs e)
{
// await Task.Run(() =>
{
this.Dispatcher.Invoke( new Action(() =>
{
Stopwatch Timer = new Stopwatch();
Timer.Start();
TimeSpan goneby = Timer.Elapsed;
string time = String.Format("{0:00}:{1:00}.{2:00}",
goneby.Minutes, goneby.Seconds,
goneby.Milliseconds / 10);
TextBlock textBlock = new TextBlock();
textBlock.Width = 100;
textBlock.Height = 50;
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.VerticalAlignment = VerticalAlignment.Top;
textBlock.Text = time;
}));
// });
}
}
}
}
這是XAML,以防萬一需要解決此問題:
<Window x:Name="window1" x:Class="WpfApp3.Window1"
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:WpfApp3"
mc:Ignorable="d"
Title="New Window" Height="300" Width="300">
<Grid>
<Button x:Name="start" Content="Start" HorizontalAlignment="Left" VerticalAlignment="Top" Width="213" Margin="38,181,0,0" Height="50" Click="start_Click"/>
</Grid>
</Window>
您需要創建Timer來更新您的Textblock:嘗試以下操作:
public partial class Window1: Window
{
DispatcherTimer dt = new DispatcherTimer();
Stopwatch sw = new Stopwatch();
string currentTime = string.Empty;
public MainWindow()
{
InitializeComponent();
dt.Tick += new EventHandler(dt_Tick);
dt.Interval = new TimeSpan(0, 0, 0, 0, 1);
}
void dt_Tick(object sender, EventArgs e)
{
if (sw.IsRunning)
{
TimeSpan ts = sw.Elapsed;
currentTime = String.Format("{0:00}:{1:00}:{2:00}",
ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
YourtextBlock.Text = currentTime;
}
}
private void startbtn_Click(object sender, RoutedEventArgs e)
{
sw.Start();
dt.Start();
}
}
原始來源: 這里
嘗試這個
<Window x:Class="WpfApp3.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:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Name="lblTime" FontSize="50" Margin="149,50,-149.333,-50.333" />
<Button x:Name="start" Content="Start" HorizontalAlignment="Left" VerticalAlignment="Top" Width="213" Margin="149,166,0,0" Height="50" Click="start_Click"/>
</Grid>
</Window>
using System;
using System.Timers;
using System.Windows;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Timer timer;
TimeSpan time;
public MainWindow()
{
InitializeComponent();
time = new TimeSpan(0);
timer = new Timer();
timer.Interval = 100;
timer.Elapsed += timer_Elapsed;
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
time += new TimeSpan(0, 0, 0, 0, 100);
this.Dispatcher.Invoke(() => {
lblTime.Text = time.ToString(@"hh\:mm\:ss\:ff");
});
}
private void start_Click(object sender, RoutedEventArgs e)
{
if (!timer.Enabled)
{
timer.Start();
start.Content = "Stop";
}
else
{
timer.Stop();
start.Content = "Start";
}
}
}
}
使用async / await是一個很好的解決方案。 請注意,由於所有代碼都在WPF線程上運行,因此沒有同步問題或不需要鎖定。
using System;
using System.Timers;
using System.Windows;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
bool running = false; // not running
TimeSpan updateTime = TimeSpan.FromSeconds(0.1);
public MainWindow()
{
InitializeComponent();
}
// Note that async void should only be used for event handlers
private async void start_Click(object sender, RoutedEventArgs e)
{
if (!running)
{
start.Content = "Stop";
var watch = StopWatch.StartNew();
while(running){
var timeSpan = watch.Elapsed;
var message =
$"Time: {timeSpan.Hours}h {timeSpan.Minutes}m " +
"{timeSpan.Seconds}s {timeSpan.Milliseconds}ms";
lblTime.Text = message
// async sleep for a bit before updating the text again
await Task.Delay(updateTime);
}
}
else
{
running = false;
start.Content = "Start";
}
}
}
}
我的簡單秒表版本:
MainWindow.xaml
<Window x:Class="Test.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:Test"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:StopwatchManager x:Key="stopwatchManager" />
</Window.Resources>
<Grid>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Source={StaticResource stopwatchManager}, Path=Stopwatch1.Duration, Mode=OneWay}" VerticalAlignment="Top" Height="27" Width="188"/>
<Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" Width="53" Click="btnStart_Click"/>
<Button x:Name="btnStop" Content="Stop" HorizontalAlignment="Left" Margin="68,42,0,0" VerticalAlignment="Top" Width="53" Click="btnStop_Click"/>
</Grid>
</Window>
MainWinwdow.xaml.cs
using System;
using System.ComponentModel;
using System.Timers;
using System.Windows;
namespace Test
{
public partial class MainWindow : Window
{
StopwatchManager stopwatchManager = new StopwatchManager();
public MainWindow()
{ InitializeComponent(); }
private void btnStart_Click(object sender, RoutedEventArgs e)
{ stopwatchManager.Stopwatch1.Start(); }
private void btnStop_Click(object sender, RoutedEventArgs e)
{ /*SaveDuration();*/ stopwatchManager.Stopwatch1.Stop(); }
}
public class StopwatchManager
{
public Stopwatch Stopwatch1 { get { return _stopwatch1; } set { _stopwatch1 = value; } }
static Stopwatch _stopwatch1 = new Stopwatch();
}
public class Stopwatch : INotifyPropertyChanged
{
private Timer timer = new Timer(100);
public event PropertyChangedEventHandler PropertyChanged;
public DateTime StartTime { get; set; } = DateTime.Now;
public double Interval
{
get { return timer.Interval; }
set { timer.Interval = value; }
}
public TimeSpan Duration { get { return DateTime.Now - StartTime; } }
public Stopwatch()
{ timer.Elapsed += timer_Elapsed; }
public void Start()
{ StartTime = DateTime.Now; timer.Start(); }
public void Stop()
{ /*SaveDuration();*/ timer.Stop(); }
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Duration")); }
}
}
去做:
-更改名稱空間(“測試”)
-實施“ SaveDuration()”
-設置UI-Updatetime => new Timer(100); //=0.1秒
-要獲得多個秒表重復或使其成為列表
public Stopwatch Stopwatch1 { get { return _stopwatch1; } set { _stopwatch1 = value; } }
static Stopwatch _stopwatch1 = new Stopwatch();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.