我正在为我的WPF应用创建自定义控件。这是我的代码:
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"/>
问题在于消息&#34; RENDERING&#34;应该每秒出现在控制台中,但它只出现一次!
我希望我的控制每秒重新渲染一次
我尝试使用InvalidateVisual()
,但该程序占用了近70%-80%的CPU资源。
如何在不使用大量系统资源的情况下重新渲染控件?
是否有类似&#34;刷新()&#34;的方法?在WinForm?
提前致谢:)
答案 0 :(得分:1)
你的设置让这个非常微弱,但你可以看到时间,如果你知道要寻找什么:
以下代码可以正常使用:
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 值的计时器来执行此操作。但是,如果它变得更复杂,您可能会对this other thread以及详细说明如何使用绘图组提高性能的答案感兴趣。