• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

C#WPF不间断地调用OnRender

c/c++ 来源:Ben 5次浏览

我正在为我的WPF应用程序创建一个自定义控件。这是我的代码:C#WPF不间断地调用OnRender

MainWindow.xaml.cs:

public sealed class MainTimer : FrameworkElement 
{ 
    public DispatcherTimer Timer = new DispatcherTimer(); 

    public MainTimer() 
    { 
     Timer.Tick += delegate 
     { 
      UpdateLayout(); 

      // No luck 
      // Dispatcher.Invoke(delegate { },DispatcherPriority.Render); 

      // InvalidateVisual(); 
     }; 
     Timer.Interval = new TimeSpan(10); 
     Timer.Start(); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     string mode = "12"; 

     Console.WriteLine("RENDERING"); 


     if (Application.Current.MainWindow != null) 
     { 
      if (mode == "24") 
      { 
       //drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(50,150,255,255)), null, BoundsRelativeTo(this, Application.Current.MainWindow)); 
       drawingContext.DrawText(new FormattedText(DateTime.Now.ToLongTimeString(), System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Microsoft PhagsPa"), 50, new SolidColorBrush(Color.FromArgb(50, 235, 255, 255))), new Point(0, -15)); 
      } 
      else 
      { 
       string st = ""; 

       if (DateTime.Now.Hour > 12) 
       { 
        st = ((DateTime.Now.Hour - 12).ToString("00") + " : " + DateTime.Now.Minute.ToString("00") + " : " + DateTime.Now.Second.ToString("00")) + " pm" ; 
       } 
       else 
       { 
        st = ((DateTime.Now.Hour).ToString("00") + " : " + DateTime.Now.Minute.ToString("00") + " : " + DateTime.Now.Second.ToString("00")) + " am"; 
       } 


       drawingContext.DrawText(new FormattedText(st, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Microsoft PhagsPa"), 40, new SolidColorBrush(Color.FromArgb(50, 200, 255, 255))), new Point(0, -12)); 
      } 
     } 
     //Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null); 

    } 

    public static Rect BoundsRelativeTo(FrameworkElement element,Visual relativeTo) 
    { 
     return 
      element.TransformToVisual(relativeTo) 
       .TransformBounds(LayoutInformation.GetLayoutSlot(element)); 
    } 

} 

MainWindow.xaml:

<Window x:Class="WpfApp1.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:WpfApp1" 
    mc:Ignorable="d" 
    ShowInTaskbar="False" 
    AllowsTransparency="True" WindowStyle="None" 
    WindowStartupLocation="Manual" 
    Left="1168" 
    Top="120" 
    ResizeMode="NoResize" 
    WindowState="Normal" 
    Title="MainWindow" Height="75.132" Width="283.621" FontFamily="Microsoft PhagsPa"> 
<Window.Background> 
    <SolidColorBrush Opacity="0" Color="LightCyan"/> 
</Window.Background> 

<local:MainTimer Loaded="Grid_Loaded"/> 

的问题是 “的渲染” 如果信息每秒出现在控制台中,但它只出现一次! 我希望我的控件每秒重新渲染一次。
我试过使用InvalidateVisual(),但程序占用了我CPU资源的近70%-80%。
如何在不使用大量系统资源的情况下重新呈现控件?
在WinForm中是否有类似于“Refresh()”的方法?

感谢提前:)


===========解决方案如下:

你的设置,使这个非常微弱的,但你可以看到的时间,如果你知道如何寻找:

enter image description here

下面的代码工作正常:

using System; 

namespace WpfApp1 
{ 
    using System.Windows; 
    using System.Windows.Media; 
    using System.Windows.Threading; 

    public sealed class MainTimer : FrameworkElement 
    { 
     private DispatcherTimer Timer = new DispatcherTimer(); 

     public MainTimer() 
     { 
      // what you are looking for is InvalidateVisual 
      this.Timer.Tick += (sender, args) => this.InvalidateVisual(); 

      // changed your timespan to a more appropriate value 
      this.Timer.Interval = TimeSpan.FromSeconds(1); 
      this.Timer.Start(); 
     } 

     protected override void OnRender(DrawingContext drawingContext) 
     { 
      string mode = "12"; 

      System.Diagnostics.Trace.WriteLine("Rendering"); 

      if (Application.Current.MainWindow != null) 
      { 
       if (mode == "24") 
       { 
        drawingContext.DrawText(new FormattedText(DateTime.Now.ToLongTimeString(), System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Microsoft PhagsPa"), 50, new SolidColorBrush(Color.FromArgb(50, 235, 255, 255))), new Point(0, -15)); 
       } 
       else 
       { 
        string st = ""; 

        if (DateTime.Now.Hour > 12) 
        { 
         st = ((DateTime.Now.Hour - 12).ToString("00") + " : " + DateTime.Now.Minute.ToString("00") + " : " + DateTime.Now.Second.ToString("00")) + " pm"; 
        } 
        else 
        { 
         st = ((DateTime.Now.Hour).ToString("00") + " : " + DateTime.Now.Minute.ToString("00") + " : " + DateTime.Now.Second.ToString("00")) + " am"; 
        } 


        drawingContext.DrawText(new FormattedText(st, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Microsoft PhagsPa"), 40, new SolidColorBrush(Color.FromArgb(50, 200, 255, 255))), new Point(0, -12)); 
       } 
      } 
     } 
    } 
} 

使用XAML:

<Window x:Class="WpfApp1.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:WpfApp1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <local:MainTimer/> 
    </Grid> 
</Window> 

它每秒渲染一次。

我仍然认为这不是定制的渲染是意味着,你可以用一个定时变更您的视图模型为此在XAML。但是,如果它变得更加复杂,您可能会对this other thread感兴趣,并且详细说明如何使用绘图组提高性能的答案。


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)