Ich erstelle ein benutzerdefiniertes Steuerelement für meine WPF-App. Dies ist mein Code:C# WPF Aufruf OnRender kontinuierlich ohne Verzögerung
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"/>
Das Problem ist, erscheint die Meldung "RENDERING" sollte erscheinen in der Konsole jede Sekunde, aber es erscheint nur einmal! Ich möchte meine Kontrolle jede Sekunde neu rendern.
Ich versuchte mit InvalidateVisual()
, aber das Programm verbraucht fast 70% -80% meiner CPU-Ressourcen.
Wie kann ich meine Steuerung ohne viele Systemressourcen erneut rendern?
Gibt es eine ähnliche Methode wie "Aktualisieren()" in WinForm?
Vielen Dank im Voraus :)
Sie scheinen nichts in Ihrem Rendering zu tun, was Sie in XAML nicht tun konnten. Gibt es einen Grund, warum du WPF umgehen und es selbst machen willst? Wenn Sie den * Wert * jede Sekunde setzen und es WPF erlauben, die UI-Zeichnung zu erstellen, scheint dies eine viel einfachere Aufgabe zu sein. – nvoigt
Ok Ich werde versuchen, Label zu verwenden, aber ich möchte immer noch wissen, wie UI ohne Verzögerung zu aktualisieren, danke für Ihren Kommentar. – Ben
BTW: Ihre Zeitspanne ist 10 * Ticks *. Das ist verdammt schnell. Sie würden etwas brauchen, das ungefähr 60000 FPS dafür tun könnte. Stellen Sie sicher, dass Sie einen Konstruktor verwenden, der Sekunden oder vielleicht Millisekunden dauert. – nvoigt