WPF/Silverlight rendering blur effect in realtime - wpf

In my WPF project I've done with clicking some UI element such stuff:
void vb1_click(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 1000);
dt.Tick += new System.EventHandler(dt_Tick);
dt.Start();
}
void dt_Tick(object sender, System.EventArgs e)
{
for(int i = 0; i < 20; i++)
{
this.vb2_blur_eff.Radius = (double)i;
}
}
The main problem is: "I can't see the each step of blur-effect per second. The program is idling and when the process is complete it gives me the final step of bluring the UI element.
I don't want it, cause both program idling is looking ugly and I want actually see the rendered result at the each period.

The main problem that I see is that you are using a For loop to set your Blur Radius, so it sits there cranks it up to max then returns control to the dispatcher which then updates it. I would prefer to do it with a StoryBoard but you can do it using a Timer and have the Timer set the Radius on each tick, when it reaches maximum then stop. You can use the Timer's interval to control the speed of the diffusion. I am using a Class level variable called count.
void vb1_click(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 20);
dt.Tick += new System.EventHandler(dt_Tick);
count = 0;
dt.Start();
}
void dt_Tick(object sender, System.EventArgs e)
{
DispatcherTimer tmr = (DispatcherTimer)sender;
this.vb2_blur_eff.Radius = (double)count;
if (count == 20)
{
tmr.Stop();
tmr.Tick -= new System.EventHandler(dt_Tick);
}
count += 1;
}

Related

wpf 3D object StoryBoard Animation point XYZ in code

I want to change 3D object point XYZ.
Is it possible ?
have you any reference? many reference tools have not Point3D Animation
how to use Point3D Property?
I want to make that :
http://www.youtube.com/watch?v=gTz7jSU-C5I
Animation
Storyboard s = new Storyboard();
ModelVisual3D MV = mainViewport.Children.ElementAt(current) as ModelVisual3D;
Model3DGroup cube = MV.Content as Model3DGroup;
for (int j = 0; j < cube.Children.Count; j++)
{
Model3DGroup Point_X= cube.Children[j] as Model3DGroup;
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.To = 2;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
s.Children.Add(doubleAnimation);
s.Duration = new Duration(TimeSpan.FromSeconds(2));
Storyboard.SetTarget(doubleAnimation, cube);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(" ??? "));
s.Begin(); // Exception during the execution.
}

How do I carry forward variable values in WinForms?

I'm trying to make it so that there is a total at the bottom depending on what buttons are pressed (when I hit the 'calculate' button). If button 1 is pressed, it shows 30 points, if button 2, it shows 60 points, if button 3 is pressed, it shows 90 points. But any or all of them can be pressed, so if 1 and 3 are pressed, it shows 120.
I know that there is some way to carry forward the value of a variable, but I can't think of it or find it (I'm very new at this). I'm also not sure if 'if' statements are the best way to handle this (especially if I end up having 25 or so buttons), so if there is a better way, please let me know.
(I have it so that the button turns lime green if pressed.)
int score1 = 0;
if (button1.BackColor == Color.Lime)
{
label10.Text = (30 + score1).ToString();
}
else label10.Text = score1.ToString();
if (button2.BackColor == Color.Lime)
{
label10.Text = (60 + score1).ToString();
}
else label10.Text = score1.ToString();
if (button3.BackColor == Color.Lime)
{
label10.Text = (90 + score1).ToString();
}
else label10.Text = score1.ToString();
Thank you.
I think you just need to add a form variable in your class to hold the running total:
private int totalScore = 0;
You can have a method to set the background color and add to the score:
private void SetBackgroundAndAddToTotal(Button button, int score)
{
if (button.BackColor != Color.Lime)
{
button.BackColor = Color.Lime;
this.totalScore = this.totalScore + score;
}
}
Inside the Click handler for each button that needs to affect the total, you can call SetBackgroundAndAddToTotal().
private void button1_Click(object sender, EventArgs e)
{
SetBackgroundAndAddToTotal(button1, 30);
}
private void button2_Click(object sender, EventArgs e)
{
SetBackgroundAndAddToTotal(button2, 60);
}
// etc.
Then, in your click handler for your "Calculate" button, you can just grab the already-calculated total from the form variable and display it:
private void btnCalculate_Click(object sender, EventArgs e)
{
label10.Text = this.totalScore.ToString();
}
Would that work?

Subclassed ListView column 0 displays corrupted text on Windows 7

Windows 7 (64 bit), .NET 4 (32 bit app)
I have a subclassed System.Windows.Forms.ListView comprising 2 columns displayed
in "Details" view. Only text fields are involved. The list comprises about 100
rows. On initial display all fields are drawn clearly but when scrolling or
"paging" with the scroll bar the text of some fields in the first column becomes
unreadable. It appears to be overwriten with random lines and blotches.
Is there anything that I can do to ensure that the text is clearly drawn in column 0?
The effect is diminished (clarity improved) when using remote desktop across a
LAN.
The effect disappears (all text is drawn clearly) when using remote desktop
across a WAN.
The ListView has always drawn perfectly on Windows XP.
For the purposes of a stripped down test, column header and DrawItem calls are ingored. The problem area is OnDrawSubItem which comprises the code
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap))
{
Rectangle rect = new Rectangle(e.Bounds.Left
,e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
e.Graphics.DrawString(e.SubItem.Text, this.Font, Brushes.Black
,rect, sf);
}
base.OnDrawSubItem(e);
}
The following is the complete code that reproduces the problem:
using System;
using System.Windows.Forms;
using System.Drawing;
///
/// Build by saving to a file called LVTrial.cs and then executing "csc LVTrial.cs"
/// Scroll list up and down on a windows 7 box and the first column of text is corrupted.
///
class MyListView : ListView
{
Random randomiser = new Random();
private const int NUM_ROWS = 100;
private const int NUM_COLS = 2;
public MyListView()
{
this.Location = new System.Drawing.Point(23, 25);
this.OwnerDraw = true;
this.Size = new System.Drawing.Size(625, 387);
this.TabIndex = 0;
this.UseCompatibleStateImageBehavior = false;
this.View = System.Windows.Forms.View.Details;
for (int ii = 0; ii < NUM_COLS; ii++)
{
this.Columns.Add((
(System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())));
}
for (int ii = 0; ii < NUM_ROWS; ii++)
{
this.Items.Add( new ListViewItem(
new string[NUM_COLS] { CreateRandomString(1, 6), CreateRandomString(1, 6) } ) );
}
}
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap))
{
Rectangle rect = new Rectangle(e.Bounds.Left
,e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
e.Graphics.DrawString(e.SubItem.Text, this.Font, Brushes.Black
,rect, sf);
}
base.OnDrawSubItem(e);
}
private string CreateRandomString(int minLength, int maxLength)
{
string str = string.Empty;
int length = randomiser.Next(minLength, maxLength + 1);
for (int ii = 0; ii < length; ii++)
{
int asciiChar = randomiser.Next(32, 126); // ascii range
str += Convert.ToChar(asciiChar);
}
return str;
}
}
class LVTrial : Form
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LVTrial());
}
private LVTrial()
{
MyListView myListView = new MyListView();
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(674, 440);
this.Controls.Add(myListView);
this.Text = "LVTrial";
}
}
I have recorded this as a Windows 7 bug at https://connect.microsoft.com/VisualStudio/feedback/details/657909/subclassed-listview-column-0-displays-corrupted-text-on-windows-7
My own workaround for the problem was to insert an additional column at position 0. I now draw a rectangle with a transparent brush in column 0 for each item. All of which stops the text in the column to the right being drawn corrupt. I imagine drawing an image would achieve the same thing but I have not tried it. You can't hide this dummy column as the problem simply transfers to the second column (i.e. the first visible coolumn).
Another tip is that it seems to be performance related. The bug was more likely to occur with 100 items in the list view than 10,000.

WPF Multitouch DeltaManipulation Mouse Events Equivalent?

i have a small demo app with a grid. this grid contains a image. i use the following code to scale and translate the image with touch.
private void manipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
Matrix matrix = imagematrix.Matrix;
matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
matrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y,
e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
imagematrix.Matrix = matrix;
e.Handled = true;
}
The matrix is placed at rendertransformation property on the image.
I would like to have the same functionality in a other demo app without touch but with mouse event handlers.
I tried something like this for the translation on mouse move but its not the same :(
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Vector delta = lastPoint - e.GetPosition(canvascontrol);
Matrix matrix = PART_MATRIX.Matrix;
if(delta.X > 0)
matrix.OffsetX += 1;
else
matrix.OffsetX -= 1;
if (delta.Y > 0)
matrix.OffsetY += 1;
else
matrix.OffsetY -= 1;
imagematrix.Matrix = matrix;
}
base.OnMouseMove(e);
}
lastPoint is the first point onmouseleftbuttondown.
Thanks.
I am not sure, if this is the answer you are looking for but, the Thumb control gives you a DragDelta, if you wrap a Thumb into a template and then assign the template to the image object, or assign the image as a template to the Thumb.

how to draw N lines per inch?

my code below is supposed to display N lines per inch. instead i get a little more than N lines per inch. the distance between lines is somewhat smaller. in addition, changing the screen resolution makes the distance between lines change too. does anyone know how to handle that?
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyApp
{
class MyControl : Control
{
private readonly ContainerVisual container = new ContainerVisual();
private readonly DrawingVisual drawing = new DrawingVisual();
private void RenderDrawing()
{
var s = PresentationSource.FromVisual(this);
var dpiX = 96 * s.CompositionTarget.TransformToDevice.M11;
var dpiY = 96 * s.CompositionTarget.TransformToDevice.M22;
double N = 1;
using (var c = drawing.RenderOpen())
{
var p = new Pen(new SolidColorBrush(Colors.Black), 1);
for (int i = 0; i < 10; i++)
{
var x = i * dpiX / N;
c.DrawLine(p, new Point(x, 0), new Point(x, 100));
}
}
}
protected override Size ArrangeOverride(Size s)
{
RenderDrawing();
return s;
}
protected override Visual GetVisualChild(int index)
{
return container;
}
protected override Size MeasureOverride(Size s)
{
return new Size();
}
protected override int VisualChildrenCount
{
get { return 1; }
}
public MyControl()
{
container.Children.Add(drawing);
AddVisualChild(container);
}
}
}
this article seems to discuss the same problem: WPF DPI issues
there is no solution to this problem other than asking the user to set the correct DPI settings that correspond to the physical DPI of the screen. a workaround that i found that makes life a little easier is to use WPF application level scaling as described here: http://www.odewit.net/ArticleContent.aspx?id=WpfDpiScaling&lang=en&format=html
Not sure if this would accomplish what you are looking for, but it should help if the issue has to do with rounding. As I said in comments, your code looks mostly correct, I think it is a rounding issue with the dpi computation. Since you are desiring to render based on 96 dpi, compute the coordinates based on 96dpi and then convert the points to your device. I wrote this more for clarity, you could use a single array of points and just remember that i is the start point and i+1 is the end point and then you would only have to make a single call to transform the points.
private void RenderDrawing()
{
var s = PresentationSource.FromVisual(this);
var dpiX = 96;
int numberOfLines = 10;
double N = 1;
double spacing = dpiX / N;
var startPoints = new Point[numberOfLines]();
var endPoints = new Point[numberOfLines]();
for (int i = 0; i < numberOfLines; i++)
{
var x = i * spacing;
startPoints[i] = new Point(x, 0);
endPoints[i] = new Point(x, 100);
}
s.CompositionTarget.TransformToDevice.Transform(startPoints);
s.CompositionTarget.TransformToDevice.Transform(endPoints);
using (var c = drawing.RenderOpen())
{
using (var p = new Pen(new SolidColorBrush(Colors.Black), 1))
{
for(int i=0; i < numberOfLines; i++)
{
c.DrawLine(p, startPoints[i], endPoints[i]);
}
}
}
}

Resources