代码之家  ›  专栏  ›  技术社区  ›  Pascal Paradis

wpf:在窗口加载时刷新/更新控件

  •  3
  • Pascal Paradis  · 技术社区  · 15 年前

    我想在标签上显示时间。加载窗口时需要自动刷新标签内容。

    我有一个简单的WPF窗口,其中有一个标签控件。如图所示

    <Window x:Class="shoes.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
        <Grid>
            <Label Margin="12" Name="lblSeconds"></Label>
            <Button Margin="68,22,135,0" Name="button1" Height="24" VerticalAlignment="Top" Click="button1_Click">Button</Button>
        </Grid>
    </Window>
    

    我已经看过这里可用的代码: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

    我做了如下修改:

    public partial class Window1 : Window
    {
        private static Action EmptyDelegate = delegate() { };
    
        public Window1()
        {
            InitializeComponent();
    
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (IsLoaded)
            {
                LoopingMethod();
            }
        }
    
        private void LoopingMethod()
        {
            while(true)
            {
                lblSeconds.Content = DateTime.Now.ToLongTimeString();
                lblSeconds.Refresh();
                Thread.Sleep(10);
            }
        }
    }
    public static class ExtensionMethods
    {
    
        private static Action EmptyDelegate = delegate() { };
    
    
        public static void Refresh(this UIElement uiElement)
        {
            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }
    }
    

    我发现当通过按钮单击事件触发代码时,它工作得很好。我试图让代码通过这样一个窗口加载的事件运行,但没有成功。窗口内容从不显示。

    当窗口加载时,我可以做什么来自动更新标签?

    3 回复  |  直到 15 年前
        1
  •  3
  •   Inferis    15 年前

    这是完全正常的,因为onload处理程序保持在无限循环中。那个循环在UI线程上,所以窗口永远不会显示。

    首先:用一个 Backgroundworker 这样它就可以在一个单独的线程上运行。

    我还将把循环代码分解成一个单独的对象实现 INotifyPropertyChanged 它用时间(字符串)公开一个属性,让该属性引发 PropertyChanged 当它改变时的事件(通过循环)。当然,你还是需要在一个单独的线程上做这个(例如使用 BackgroundWorker )使用绑定将专用对象绑定到标签。

    另一种策略是 Timer 它定期进行回调,您可以在那里更新标签。

        2
  •  3
  •   user83286    15 年前

    我将编写一个类,该类使用CurrentTime属性实现InotifyPropertyChanged接口,并包含一个DispatcherTimer实例,该实例将定期引发PropertyChanged(“CurrentTime”)事件。

    然后将这个对象放到表单的资源中,并将标签的内容绑定到currentTime属性。

    DispatcherTimer使用消息泵,因此不涉及不必要的线程。

        3
  •  1
  •   Nir    15 年前

    不要使用无限循环,而是使用DispatcherTimer