R
Rainer Queck
Hello NG,
In order to viaualize a production line, transporting a couple thousands
"defects" objects , I wrote a little WPF application, where each object is
reprsented as a little rectangle on a Canvas.
To This "production line" I am adding objects in a Timer.Intervall of 5 mS
The position of these objects is calculated in a variable Timer.Intervall
10...150 milliseconds, depending on the time I need to recalculate the
objects position).
as long as there are only a few object on the line, the behaviour of the
WPF-App is nice. If I decreas the line speed - resulting in more objects on
the line - the persentation of the objects gets very "bumpy". It is far away
of a smoth motion.
I assum , the way I am doing this might be not the most optimal one. So my
question is, what would be the best approach to this task?
Regards
Rainer Queck
P.S: the code with the two most important methods.
/// <summary>
/// This method takes care, that all ribbon objects are painted to
the given canvas.
/// </summary>
public void Paint()
{
GuiInvokeDelegate aDelegate = new
GuiInvokeDelegate(InvokePaint);
ribbonCanvas.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
aDelegate);
}
/// <summary>
/// This mehtod mustbe called in-synch with the gui. It controls all
visual ribbon objects and updates them
/// </summary>
private void InvokePaint()
{
try
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int i = 0;
ribbon.Update();
while (i < ribbon.DefectList.Count)
{
Defect defect = ribbon.DefectList;
Rectangle rect = null;
if(!dicDefect.TryGetValue(defect, out rect))
{
rect = new Rectangle();
rect.Stroke = Brushes.Black;
rect.Fill = Brushes.Black;
dicDefect[defect] = rect;
rect.MouseDown += new
System.Windows.Input.MouseButtonEventHandler(rect_MouseDown);
ribbonCanvas.Children.Add(rect);
}
rect.Width = MillimeterToCanvas(defect.Width);
rect.Height = MillimeterToCanvas(defect.Height);
Canvas.SetTop(rect, MillimeterToCanvas(defect.YPos));
Canvas.SetLeft(rect,
MillimeterToCanvas(ribbon.CountToMillimeter(defect.XPosCnt)));
i++;
}
// remove no longer needed rechtangles...
Dictionary<Defect, Rectangle>.KeyCollection defects =
dicDefect.Keys;
List<Defect> toBeRemoved = new List<Defect>();
foreach (Defect d in defects)
{
if (!ribbon.DefectList.IsMember(d))
{
toBeRemoved.Add(d);
}
}
foreach (Defect d in toBeRemoved)
{
ribbonCanvas.Children.Remove(dicDefect[d]);
dicDefect.Remove(d);
}
stopWatch.Stop();
if (stopWatch.ElapsedMilliseconds > lastMilliSeconds)
{
lastMilliSeconds = stopWatch.ElapsedMilliseconds;
updateIntervall = Convert.ToInt32(lastMilliSeconds);
}
else
{
double dt = lastMilliSeconds -
stopWatch.ElapsedMilliseconds;
if (dt > 10)
{
lastMilliSeconds--;
updateIntervall = Convert.ToInt32(lastMilliSeconds);
}
}
}
catch (Exception ex)
{
string eMsg = String.Format("Exception in
RibbonVisualizer.InvokePaint: {0}",ex.Message);
FileDiagnose.Instance.ReportError(eMsg);
}
}
In order to viaualize a production line, transporting a couple thousands
"defects" objects , I wrote a little WPF application, where each object is
reprsented as a little rectangle on a Canvas.
To This "production line" I am adding objects in a Timer.Intervall of 5 mS
The position of these objects is calculated in a variable Timer.Intervall
10...150 milliseconds, depending on the time I need to recalculate the
objects position).
as long as there are only a few object on the line, the behaviour of the
WPF-App is nice. If I decreas the line speed - resulting in more objects on
the line - the persentation of the objects gets very "bumpy". It is far away
of a smoth motion.
I assum , the way I am doing this might be not the most optimal one. So my
question is, what would be the best approach to this task?
Regards
Rainer Queck
P.S: the code with the two most important methods.
/// <summary>
/// This method takes care, that all ribbon objects are painted to
the given canvas.
/// </summary>
public void Paint()
{
GuiInvokeDelegate aDelegate = new
GuiInvokeDelegate(InvokePaint);
ribbonCanvas.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
aDelegate);
}
/// <summary>
/// This mehtod mustbe called in-synch with the gui. It controls all
visual ribbon objects and updates them
/// </summary>
private void InvokePaint()
{
try
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int i = 0;
ribbon.Update();
while (i < ribbon.DefectList.Count)
{
Defect defect = ribbon.DefectList;
Rectangle rect = null;
if(!dicDefect.TryGetValue(defect, out rect))
{
rect = new Rectangle();
rect.Stroke = Brushes.Black;
rect.Fill = Brushes.Black;
dicDefect[defect] = rect;
rect.MouseDown += new
System.Windows.Input.MouseButtonEventHandler(rect_MouseDown);
ribbonCanvas.Children.Add(rect);
}
rect.Width = MillimeterToCanvas(defect.Width);
rect.Height = MillimeterToCanvas(defect.Height);
Canvas.SetTop(rect, MillimeterToCanvas(defect.YPos));
Canvas.SetLeft(rect,
MillimeterToCanvas(ribbon.CountToMillimeter(defect.XPosCnt)));
i++;
}
// remove no longer needed rechtangles...
Dictionary<Defect, Rectangle>.KeyCollection defects =
dicDefect.Keys;
List<Defect> toBeRemoved = new List<Defect>();
foreach (Defect d in defects)
{
if (!ribbon.DefectList.IsMember(d))
{
toBeRemoved.Add(d);
}
}
foreach (Defect d in toBeRemoved)
{
ribbonCanvas.Children.Remove(dicDefect[d]);
dicDefect.Remove(d);
}
stopWatch.Stop();
if (stopWatch.ElapsedMilliseconds > lastMilliSeconds)
{
lastMilliSeconds = stopWatch.ElapsedMilliseconds;
updateIntervall = Convert.ToInt32(lastMilliSeconds);
}
else
{
double dt = lastMilliSeconds -
stopWatch.ElapsedMilliseconds;
if (dt > 10)
{
lastMilliSeconds--;
updateIntervall = Convert.ToInt32(lastMilliSeconds);
}
}
}
catch (Exception ex)
{
string eMsg = String.Format("Exception in
RibbonVisualizer.InvokePaint: {0}",ex.Message);
FileDiagnose.Instance.ReportError(eMsg);
}
}