C#WPF调用OnRender连续无延迟

C#WPF调用OnRender连续无延迟,c#,wpf,xaml,controls,render,C#,Wpf,Xaml,Controls,Render,我正在为我的WPF应用程序创建自定义控件。这是我的代码: MainWindow.xaml.cs: MainWindow.xaml: 问题是消息“RENDERING”应该每秒出现在控制台中,但它只出现一次! 我希望我的控件每秒都重新渲染。 我尝试使用InvalidateVisual(),但该程序占用了我将近70%-80%的CPU资源如何在不使用大量系统资源的情况下重新呈现控件? WinForm中是否有类似于“Refresh()”的方法 提前感谢:)您的设置使这非常模糊,但如果您知道要查找什么

我正在为我的WPF应用程序创建自定义控件。这是我的代码:

MainWindow.xaml.cs:

MainWindow.xaml:


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


提前感谢:)

您的设置使这非常模糊,但如果您知道要查找什么,您可以看到时间:

以下代码可以正常工作:

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中通过计时器更改viewmodel值来实现这一点。但是,如果问题变得更复杂,您可能会对详细说明如何使用图形组提高性能的答案感兴趣。

在渲染中,您似乎没有做任何在XAML中做不到的事情。你有没有理由想绕过WPF,自己去做?每秒设置一次值并让WPF绘制UI似乎是一项容易得多的任务。好的,我会尝试使用Label来做,但我仍然想知道如何不延迟地更新UI,谢谢你的评论。顺便说一句:你的时间跨度是10个刻度。太快了。你需要的东西,可以做约60000 FPS的。确保你使用的构造函数需要几秒甚至几毫秒。我认为问题在于时间跨度,现在我的程序几乎耗尽了你的欢迎时间:)顺便说一句:这个应用程序用于我的桌面小工具,所以我将颜色设置为透明。谢谢你回答我的问题!
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));
                }
            }
        }
    }
}
<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>