簡體   English   中英

在WPF中實時更新文本框不給出錯誤且沒有輸出

[英]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();

來源GIT-Hub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM