I have the following code in my Universal App (Windows Phone):
void colourPicker_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
PicturePicker picturePicker = sender as PicturePicker;
GeneralTransform transform = picturePicker.TransformToVisual(ImageHolder);
Point controlPosition = transform.TransformPoint(new Point(0, 0));
int pointX = (int)controlPosition.X;
int pointY = (int)controlPosition.Y;
Color c = writeableBmp.GetPixel(pointX, pointY);
// WriteableBitmap newWB = writeableBmp.Crop(pointX - 21, pointY - 21, 42, 42);
// picturePicker.SetImageBrush(newWB);
SolidColorBrush brush = new SolidColorBrush(c);
picturePicker.SetColor(brush);
Canvas.SetLeft(picturePicker, Canvas.GetLeft(picturePicker) + e.Delta.Translation.X);
Canvas.SetTop(picturePicker, Canvas.GetTop(picturePicker) + e.Delta.Translation.Y);
}
I have a image, and on top of that a UserControl (very simple XAML) that the user can drag around to find the color he/she wants. Only dragging works great on ManipulationDelta, but when I try to GetPixel() everytime the ManipulationDelta event triggers the translate becomes very laggy. If I comment out the setting of the color (picturePicker.SetColor) it's still slow, so that's not the problem.
Weird enough, very similiar code worked fluid in the old version of this app in Silverlight (on the same phone).
Any thoughts on how to improve this?
Related
I'm developing a Windows Form application with WPF User Control embedded in the WF. If I add a button and execute my userControl.DrawWireFrameCube(); My ViewPort3D get updated. I'm using Helix 3D Toolkit. But If I call my method from my MainWindowForm class it doesn't get executed and UI is not updated,but only userControl.DrawWireFrameCube(); isn't working. The other userControl.Draw3DObject(insertionPoint, points, color); method is working fine.
private void VisualizePart(int index)
{
InsertionPoint insertionPoint = new InsertionPoint
{
X = _duplicatedListParts[index].INFO1,
Y = _duplicatedListParts[index].INFO2,
Z = _duplicatedListParts[index].INFO3
};
DetailSize points = new DetailSize
{
Length = _duplicatedListParts[index].LENGTH,
Width = _duplicatedListParts[index].WIDTH,
Thickness = _duplicatedListParts[index].THICKNESS
};
userControl.Dispatcher.Invoke(() =>
{
System.Windows.Media.Color color = System.Windows.Media.Color.FromRgb(255, 90, 0);
userControl.Draw3DObject(insertionPoint, points, color);
userControl.DrawWireFrameCube();
});
}
The difference is that in my Draw3DObject() I add items to Model3DGroup and in DrawWireFrameCube() I add items to MyViewPort3D. I'm not using XAML and I want to stay that way.
Any ideas what is wrong here?
P.S I love negative vote without explanation :)
I am trying to create a elipse in a textbox on double click. But it doesnt seem to happen.
panel.MouseClick += create_terms;
private void create_terms(object sender, EventArgs arg)
{
if (Phys_terms_check.Checked == true)
{
MouseEventArgs e = (MouseEventArgs)arg;
Graphics g = CreateGraphics();
SolidBrush p = new SolidBrush(Color.Red);
Pen erase = new Pen(Color.White);
Panel panel = (Panel)sender;
g.FillEllipse(p, e.X+panel.Left,e.Y+panel.Top,10,10);
}
}
The e.x and e.y seem to be giving relative coordinates from the sender. How to get point relative to the form.
add sender's top and left coordinates.
g.FillEllipse(p, e.X + textbox.Left, e.Y + textbox.Top, 10, 10);
but, this won't show, because textbox paint event fill fire and repaint textbox.
First of all: TextBoxes are old legacy and rather special Controls that do not support all things normal controls let you do.
Among the things that won't work are
Setting a BackgroundImage
Owner-drawing them
The latter includes any drawing in its Paint/OnPaint events.
You can code and hook-up the Paint event, but it won't get called.
You still can draw onto a TextBox using CreateGraphics, if you do it right, but as always with this function the result is non-persistent and will go away as soon as the system refreshes the TextBox itself, which is super-fast: as soon as you move your cursor over it the circle you draw may disappear..
The code to do it would have to look similar to this:
Graphics g = yourTextBox.CreateGraphics();
g.FillEllipse(Brushes.Red, yourTextBox.Width - 22, 2, 11, 11);
But as I said this will not persist, so it has little or no value.
If you want to draw onto something with a visible Text property you can use a Label:
private void yourLabel_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillEllipse(Brushes.Red, yourLabel.Width - 22, 2, 11, 11);
}
The result looks the same, but only the dot in the Label will persist, e.g. a Minimize-Maximize of the form.. In fact the dot in the TextBox didn't even survive calling my screenshot program, so I had use resort to pressing the Print-Key !
For drawing circles upon mouseclicks onto normal controls see this post!
I have a C# WinForm that has a transparent key of Lime. I also set the background color of the form to Lime. This works great for things like buttons and almost anything you can think of. The form looks like it is not there and allows me to create a custom looking form.
I have a picture box with background of Transparent and the picture box image is has a drop shadow. When I run the application, the drop shadow is not transparent. The drow shadow has a background color of the forms background color (lime). It looks horrible.
How do I have a transparent form that also allows transparent images to be placed on it properly.
Programs such as SWTOR game launcher have this nice background drop shadow so I know it is possible.
Thank You!
You're looking for one of two things, either Windows Regions
OR
Layered Windows
Here is an excellent example for C#
Or a little example i put together:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
GraphicsPath gp = new GraphicsPath();
Region r;
PointF[] p = new PointF[9];
p[0] = new PointF(70, 0);
p[1] = new PointF(170, 0);
p[2] = new PointF(240, 70);
p[3] = new PointF(240, 170);
p[4] = new PointF(170, 240);
p[5] = new PointF(70, 240);
p[6] = new PointF(0, 170);
p[7] = new PointF(0, 70);
p[8] = new PointF(70, 0);
gp.AddPolygon(p);
r = new Region(gp);
this.Region = r;
gp.Dispose();
r.Dispose();
}
you will need to put this code into the form you want it to effect.
I'm busy with a small application in which I want to display information at the location of the cursor when it hoovers over a Canvas. The Canvas in question is a custom one (inherited from Canvas) which provides functionality to add DrawingVisuals (as shown in basically every tutorial on displaying large amounts of geometric shapes on a canvas).
I would like to display a vertical line and horizontal line as well as the local coordinates (p in the code below) which are directly derived from the canvas coordinates (v). At the moment I'm rendering these objects at position (0,0) and use offset during the OnMouseMove event to update their location.
The horizontal and vertical lines are rendered in the DrawingVisual _cursor and the location in local y,z-coordinates in _info.
private void oCanvas_MouseMove(object sender, MouseEventArgs e)
{
#region 1. Get location data
System.Windows.Vector v = (System.Windows.Vector)e.GetPosition(oCanvas);
// point in YZ coordinates
BSMath.DoubleXY p = new BSMath.DoubleXY();
p.X = (oCanvas.OriginY - v.Y) / oCanvas.ZoomFactor;
p.Y = (oCanvas.OriginX - v.X) / oCanvas.ZoomFactor;
#endregion
#region 2. Update cursor and info
if (oSettings.ShowInformation)
{
_info.Info = p.X.ToString("0.0") + " | " + p.Y.ToString("0.0");
_info.Render(0, 0);
_info.Visual.Offset = v;
}
// move cursor
_cursor.Visual.Offset = v;
}
Using the mousemove event seems to be creating a lot of overhead and I can see that there are issues tracking the mouse movements when I move the mouse quickly.
Can anyone recommend a better way of creating the same effect?
example http://www.iccg.be/test/images/canvas.jpg
Edit:
I investigated it a bit further and the problem seems to occur when the resolution of the canvas is bigger. If it is a 600x400 canvas then there is no delay, but when it is around 1000x800 I get the problem with delays when hoovering. The performance also improves if I use user drawn crosshairs instead of the lines that have the full width/ height of the canvas.
I recently have built something similar and haven't had any performance issues.
Did it the very simple way by adding the stuff directly on the canvas.
The drawn items are in a second canvas behind the mouse position canvas. Both reside in a Grid.
This is for sure not the most sophisticated way to solve this, but it works quite well for me.
Here's the code:
private Point _previous;
private Point _current;
private Line _xLine;
private Line _yLine;
private TextBlock _displayTextBlock;
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
_current = e.GetPosition(myCanvas);
if (_previous != _current)
{
if (_xLine == null)
{
_xLine = new Line() {X1 = 0, X2 = myCanvas.ActualWidth, Stroke = new SolidColorBrush(Colors.Black)};
_yLine = new Line() {Y1 = 0, Y2 = myCanvas.ActualHeight, Stroke = new SolidColorBrush(Colors.Black)};
_displayTextBlock = new TextBlock();
myCanvas.Children.Add(_xLine);
myCanvas.Children.Add(_yLine);
myCanvas.Children.Add(_displayTextBlock);
}
_displayTextBlock.SetValue(Canvas.TopProperty, _current.Y);
_displayTextBlock.SetValue(Canvas.LeftProperty, _current.X);
_displayTextBlock.Text = _current.X.ToString() + " | " + _current.Y.ToString();
_xLine.Y1 = _current.Y;
_xLine.Y2 = _current.Y;
_yLine.X1 = _current.X;
_yLine.X2 = _current.X;
_previous = _current;
}
}
Ok so im starting to get stuck into my design and get the style right.
My Theme is using a kryptonForm style GUI but kyryptonForms do not not have a pre designed ListView, so im having to build this myself
My Application is a messenger system based on XMPP/Jabber so you can guess how i would like my contact list to be designed.
i have done most of the positioning but im struggling on styling each contact row.
Im aiming for some transparent overlay simmerler to the MSN Live messenger Contact List
Heres my OnDraw Event code atm and im struggling to figure out the best way to do the gradient
private void ContactItem_OnPaintDraw(object sender, DrawListViewItemEventArgs e)
{
Rectangle ImageRect = e.Bounds;
ImageRect.Inflate(-2, -2);
ImageRect.Width = 32;
Rectangle TextRect = e.Bounds;
TextRect.X = ImageRect.Right + 2;
TextRect.Width = e.Bounds.Width - TextRect.X;
Rectangle IconRect = TextRect;
IconRect.Inflate(-1, 0);
IconRect.Y = ImageRect.Bottom - 16;
IconRect.Width = 16;
IconRect.Height = 16;
if ((e.State & ListViewItemStates.Selected) != 0)
{
// Draw the background and focus rectangle for a selected item.
e.Graphics.FillRectangle(ContactListBackgroundBrush, e.Bounds);
e.DrawFocusRectangle();
}
else
{
// Draw the background for an unselected item.
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
}
if (ListViewContacts.View != View.Details)
{
e.Graphics.DrawImage((Image)Resources.UserIconDefault, ImageRect);
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, TextRect, e.Item.ForeColor, TextFormatFlags.GlyphOverhangPadding);
}
}
And the ContactListBackgroundBrush var is like so
private Brush ContactListBackgroundBrush = new SolidBrush(Color.FromArgb(33, 162, 191));
its this that i need to convert to the styled element
alt text http://screensnapr.com/u/yeq8o0.png
Im Looking to get this Highlighted style without importing any specific windows 7 DLL files as the App is used for windows XP as well.
Hope you guys can help me :)
You can define a brush as a LinearGradientBrush, look for the msnd documentation. This is IMHO the best way, to draw gradiants..