问题描述
我的工作让我的应用程序,它从串口读取数据并更新UI上更有效的一计,我想问在我的code一些建议,处理用户界面的变化。我有一个定时器设置检查数据被发送到COM端口和更新从COM端口接收的变量的UI另一个计时器。基本上正在发生的事情是我旋转计。这里是我的code用于处理图形...
I am working on making my application that reads data from the serial port and updates a gauge on the UI more efficient and I wanted to ask for some advice on my code that processes the UI changes. I have a timer set to check for data being sent to the COM port and another timer that updates the UI with the variable received from the COM port. Basically what is happening is I am rotating a gauge. Here is my code for handling the graphics...
void timer_Tick(object sender, EventArgs e) //Timer regulates how often the gauge is updated on the UI
{
if (pictureBox1.Image != null)
pictureBox1.Image.Dispose(); // dispose old image (you might consider reusing it rather than making a new one each frame)
Point test = new Point((int)_xCor, (int)_yCor);
Image img = new Bitmap(400, 400); // The box tht contains the image <--- Play around with this more
pictureBox1.Image = img; // Setting the img Image to the pictureBox class?
Graphics g = Graphics.FromImage(pictureBox1.Image); // G represents a drawing surface
Matrix mm1 = new Matrix();
//
mm1.RotateAt((float)(90 + (((12.5 * state) - 20.95)*6)), new Point((int)_xrotate, (int)_yrotate), MatrixOrder.Append);
GraphicsPath gp = new GraphicsPath();
g.Transform = mm1; // transform the graphics object so the image is rotated
g.DrawImage(imgpic, test); // if the image needs to be behind the path, draw it beforehand
mm1.Dispose();// prevent possible memory leaks
gp.Dispose();// prevent possible memory leaks
g.Dispose(); // prevent possible memory leaks
pictureBox1.Refresh();
}
我想知道,如果有,我可以在屏幕上旋转图像更有效的方式。我觉得自己必须有,但我无法弄清楚。
I am wondering if there is a more efficient way that I can rotate the Image on screen. i feel like there has to be but I can't figure it out.
推荐答案
这是我第二次为一个WinForms问题WPF的解决方案。
This is the second time I provide a WPF solution for a winforms problem.
只需复制并粘贴我的code在文件 - >新建项目 - > WPF应用程序,看看实际效果如何
Just copy and paste my code in a file -> new project -> WPF Application and see the results for yourself.
另外看看多么简单此code真的是(我使用的是随机值,这样你可以删除它适应您的需求)。
Also take a look at how simple this code really is (I'm using random values, so you can remove that and adapt it to your needs).
我使用的图纸(即&LT;路径/&GT;
XAML中的一部分)是不够的计。我只是有这条道路已绘制和我懒得来创建一个新的。您应该创建一个新的绘图(我推荐使用防爆pression混合)。但是你可以看到正在应用的旋转和它是如何工作的快。
The drawing I used (the <Path/>
part in XAML) is not adequate for a Gauge. I just had that Path already drawn and I'm too lazy to create a new one. You should create a new drawing (I recommend using Expression Blend). But you can see the Rotation being applied and how fast it works.
using System;
using System.Threading;
using System.Windows;
using System.ComponentModel;
namespace WpfApplication4
{
public partial class Window2
{
public Window2()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
public class ViewModel: INotifyPropertyChanged
{
private double _value;
public double Value
{
get { return _value; }
set
{
_value = value;
NotifyPropertyChange("Value");
}
}
private int _speed = 100;
public int Speed
{
get { return _speed; }
set
{
_speed = value;
NotifyPropertyChange("Speed");
Timer.Change(0, value);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChange(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private System.Threading.Timer Timer;
public ViewModel()
{
Rnd = new Random();
Timer = new Timer(x => Timer_Tick(), null, 0, Speed);
}
private void Timer_Tick()
{
Application.Current.Dispatcher.BeginInvoke((Action) (NewValue));
}
private Random Rnd;
private void NewValue()
{
Value = Value + (Rnd.Next(20) - 10);
}
}
}
XAML:
<Window x:Class="WpfApplication4.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" WindowState="Maximized">
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<TextBlock Text="Delay (MS):" Margin="2"/>
<Slider Width="200" Minimum="100" SmallChange="1" LargeChange="10" Maximum="1500" Value="{Binding Speed}" Margin="2"/>
<TextBlock Text="Current Value:" Margin="2"/>
<TextBox Text="{Binding Value}" Margin="2"/>
</StackPanel>
<Path Data="M0.95991516,0.5 L73.257382,1.866724 90.763535,1.866724 90.763535,90.822725 66.430534,90.822725 66.430534,26.075016 0.5,24.828653 z" Fill="#FF506077" RenderTransformOrigin="0.861209625003783,0.507482926584064" Stretch="Fill" Stroke="Black">
<Path.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleY="1" ScaleX="-1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="{Binding Value}" x:Name="Rotation"/>
<TranslateTransform/>
</TransformGroup>
</Path.LayoutTransform>
</Path>
</DockPanel>
</Window>
这篇关于使用定时器在C#中更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!