public void CreateALine(double x1, double y1)
{
// Create a Line
Line redLine = new Line();
redLine.X1 = x + 20;
redLine.Y1 = y + 20;
redLine.X2 = x1 + 20;
redLine.Y2 = y1 + 20;
SolidColorBrush gBrush = new SolidColorBrush();
gBrush.Color = Colors.Green;
redLine.StrokeThickness = 2;
redLine.Stroke = gBrush;
// Add line to the Canvas
canvas2.Children.Add(redLine);
}
Here is my code, now I want to delete this line, can anyone tell me how to do this?
thanks.
The Children property is nothing more than a UIElementCollection object attached to the Canvas control.
The UIElementCollection object has some methods that allow you to remove objects from itself, which may vary depending on the programming language.
In your case, the Remove and RemoveAt should solve your problem. All you need to do is to hold a reference of the item you want to remove and pass it as a parameter to the appropiate remove method unless you know its index in the collection; in which case you can remove it using that instead.
Related
I'm working with Actionscript 2 (not ready to upgrade yet, although it's irreverent to the problem) but I'm having trouble with OOP and classes.
I've got a "Tool" class, written like so:
class com.Tool {
public var self:MovieClip;
private static var Type:String;
function Tool(T:String, X:Number, Y:Number) {
Type = T;
self = _root.createEmptyMovieClip("obj"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
self._x = X;
self._y = Y;
self.width = 36;
self.height = 36;
self.onRollOver = function() {
trace(Type);
}
}
}
I create 3 of them in the main script like so:
var toolPan:Tool = new Tool("pan", 0, 0);
var toolSquare:Tool = new Tool("square", 0, 38);
var toolLine:Tool = new Tool("line", 0, 76);
It all works great, except the onRollOver. It's supposed to output the unique "Type" string, but it always outputs "line" (the last Type Tool created) regardless which one I roll over.
Needless to say, I'm still a beginner to all this. But it seems like they're all sharing the same variable :/ How do I make these variables unique to each object created?
Thank you very much!
It's because it's type static, so the value is shared by all instances of that class. Remove it and it should work.
private var Type:String;
After I set a column's WrapText=true, I want to see what the new height of the row will be (i.e. if the text wraps, for how many lines). It appears that the Height property of a row is not updated.
ExcelPackage pkg = new ExcelPackage();
ExcelWorksheet sheet = pkg.Workbook.Worksheets.Add("Test");
// height is 15.0
double heightBefore = sheet.Row(1).Height;
sheet.Cells[1, 1].Value = "Now is the time for all good men to come to the aid of their country";
ExcelColumn col = sheet.Column(1);
// this will resize the width to 60
col.AutoFit();
if (col.Width > 50)
{
col.Width = 50;
// this is just a style property, and doesn't actually execute any recalculations
col.Style.WrapText = true;
}
// so this is still 15.0. How do I get it to compute what the size will be?
double heightAfter = sheet.Row(1).Height;
// open the xls, and the height is 30.0
pkg.SaveAs(new System.IO.FileInfo("text.xlsx"));
In fact, a search for the Height property (or the underlying field _height) shows that it is only set by the property setter, and does not ever seem to be set based on anything else (like content in the row).
Any ideas on how I can get a refreshed Height for a row?
Thanks
The general pattern I've noticed with EPPlus is that it generates the framework of the document with the minimum amount of information necessary. Then, when you open the file, Excel fills out the remaining XML structure, which is why you always have to save the file after opening an EPPlus generated document.
For your question, I'm assuming that Excel is updating the row heights after you open the Excel file so EPPlus would not have the updated row height information. I'm not absolutely certain that the library doesn't support this, but like you I was unable to find a way to get the updated values.
One workaround however could be to just calculate what the value would be since you know your text length and column width:
ExcelPackage pkg = new ExcelPackage();
ExcelWorksheet sheet = pkg.Workbook.Worksheets.Add("Test");
// height is 15.0
double heightBefore = sheet.Row(1).Height;
var someText = "Now is the time for all good men to come to the aid of their country. Typewriters were once ground-breaking machines.";
sheet.Cells[1, 1].Value = someText;
ExcelColumn col = sheet.Column(1);
ExcelRow row = sheet.Row(1);
// this will resize the width to 60
col.AutoFit();
if (col.Width > 50)
{
col.Width = 50;
// this is just a style property, and doesn't actually execute any recalculations
col.Style.WrapText = true;
}
// calculate the approximate row height and set the value;
var lineCount = GetLineCount(someText, (int)col.Width);
row.Height = heightBefore * lineCount;
// open the xls, and the height is 45.0
pkg.SaveAs(new System.IO.FileInfo("text.xlsx"));
Here's the method to calculate the number of lines:
private int GetLineCount(String text, int columnWidth)
{
var lineCount = 1;
var textPosition = 0;
while (textPosition <= text.Length)
{
textPosition = Math.Min(textPosition + columnWidth, text.Length);
if (textPosition == text.Length)
break;
if (text[textPosition - 1] == ' ' || text[textPosition] == ' ')
{
lineCount++;
textPosition++;
}
else
{
textPosition = text.LastIndexOf(' ', textPosition) + 1;
var nextSpaceIndex = text.IndexOf(' ', textPosition);
if (nextSpaceIndex - textPosition >= columnWidth)
{
lineCount += (nextSpaceIndex - textPosition) / columnWidth;
textPosition = textPosition + columnWidth;
}
else
lineCount++;
}
}
return lineCount;
}
One thing to keep in mind is that Excel has a max row height of 409.5 so you'll want to make sure your column width is not so narrow that you'll reach this limit.
Also, another thing I noticed is that the column widths that you manually set with EPPlus don't actually set the columns to the expected value. For example, if you set your column width to 50, you'll notice that the actual column width is set to 49.29 so you may want to factor that in as well.
I am doing a very simple stuff, my goal is to move one skeleton based on the position of the other skeleton, for this i am based myself on a HipCenter position.
(This algoritm could be wrong, this question is about a exception ocurring in the foreach loop)
Here is my actual code:
public static Skeleton MoveTo(this Skeleton skOrigin, Skeleton skDestiny)
{
Skeleton skReturn = skOrigin; // just making a copy
// find the factor to move, based on the HipCenter.
float whatToMultiplyX = skOrigin.Joints[JointType.HipCenter].Position.X / skDestiny.Joints[JointType.HipCenter].Position.X;
float whatToMultiplyY = skOrigin.Joints[JointType.HipCenter].Position.Y / skDestiny.Joints[JointType.HipCenter].Position.Y;
float whatToMultiplyZ = skOrigin.Joints[JointType.HipCenter].Position.Z / skDestiny.Joints[JointType.HipCenter].Position.Z;
SkeletonPoint movedPosition = new SkeletonPoint();
Joint movedJoint = new Joint();
foreach (JointType item in Enum.GetValues(typeof(JointType)))
{
// Updating the position
movedPosition.X = skOrigin.Joints[item].Position.X * whatToMultiplyX;
movedPosition.Y = skOrigin.Joints[item].Position.Y * whatToMultiplyY;
movedPosition.Z = skOrigin.Joints[item].Position.Z * whatToMultiplyZ;
// Setting the updated position to the skeleton that will be returned.
movedJoint.Position = movedPosition;
skReturn.Joints[item] = movedJoint;
}
return skReturn;
}
Using F10 to debug everything works fine ultin the second pass in te foreach loop.
When i am passing for the second time in the foreach i get a exception on this line
skReturn.Joints[item] = movedJoint;
The exception says:
JointType index value must match Joint.JointType
But the value is actualy the Spine.
Whats wrong?
Solved, here is the solution
Joint newJoint = new Joint(); // declare a new Joint
// Iterate in the 20 Joints
foreach (JointType item in Enum.GetValues(typeof(JointType)))
{
newJoint = skToBeMoved.Joints[item];
// applying the new values to the joint
SkeletonPoint pos = new SkeletonPoint()
{
X = (float)(newJoint.Position.X + (someNumber)),
Y = (float)(newJoint.Position.Y + (someNumber)),
Z = (float)(newJoint.Position.Z + (someNumber))
};
newJoint.Position = pos;
skToBeChanged.Joints[item] = newJoint;
}
This will work.
How can I add some text on top of a bar in a chart.
This is the code I have to add the bar:
var color = ColorTranslator.FromHtml(row.Colour);
var barItem = graphPane.AddBar(row.Propensity.ToString(), null, Ys.ToArray(), color);
Thank you
Here is a quick example using TextObj to simply add labels to each bar.
GraphPane myPane = zedGraphControl1.GraphPane;
double[] y = { 100, 50, 75, 125 };
BarItem myBar = myPane.AddBar("Data", null, y, Color.Red);
for (int i = 0; i < myBar.Points.Count; i++)
{
TextObj barLabel = new TextObj(myBar.Points[i].Y.ToString(), myBar.Points[i].X, myBar.Points[i].Y + 5);
barLabel.FontSpec.Border.IsVisible = false;
myPane.GraphObjList.Add(barLabel);
}
myBar.Label.IsVisible = true;
zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();
Of course this just uses the value of the data as the label. If you wanted to use custom labels, you could create a string array or list and use that inside the loop.
Here are some ZedGraph references:
Introduction and examples: http://www.codeproject.com/KB/graphics/zedgraph.aspx
Source code documentation: http://zedgraph.sourceforge.net/documentation/default.html
You need to define AlignH and AlignV in your text object:
TextObj textLabel = new TextObj(value.ToString(), positionX, value, CoordType.AxisXYScale, AlignH.Center, AlignV.Top);
AlignV define the position of your value on the bar.
Providing you want the label text to match the value of each bar, then you can do it with a single line of code:
BarItem.CreateBarLabels(graphPane, false, "F0");
Note that the 3rd parameter is a double.ToString format. e.g. "F0" = 12, "F2" = 12.34
However, if you want any flexibity with it then this solution is not ideal. It also doesn't work very well if you have a stacked bar chart, because having any 0 value data will cause labels to overlap and look horrific
In the Winforms RichTextBox control I have previously used the GetLineFromCharIndex method and the GetFirstCharIndexOfCurrentLine to work out the start and end points of the typed text on he current line.
I am struggling with the new RichTextBox control in Silverlight 4 as there doesn't appear to be equivalent methods. GetPositionFromPoint is available but seems a but clunky.
Cheers.
Updated...I have gone someway to making this work but this requires me to use the Select method of the control, this feels very wrong...
private string GetCurrentLine()
{
TextPointer prevSelStart = richTextBox1.Selection.Start;
Point lineStart = new Point(0, prevSelStart.GetCharacterRect(LogicalDirection.Forward).Y);
TextPointer prevSelEnd = richTextBox1.Selection.End;
TextPointer currentLineStart = richTextBox1.GetPositionFromPoint(lineStart);
//need to find a way to get the text between two textpointers
//other than performing a temporary selection in the rtb
richTextBox1.Selection.Select(currentLineStart, prevSelStart);
string text = richTextBox1.Selection.Text;
//revert back to previous selection
richTextBox1.Selection.Select(prevSelStart, prevSelEnd);
return text;
}
I don't think you can't avoid the selection, it's a proper way to do it (the "selection" is just a logical one), but you can avoid GetPositionFromPoint with TextPointer.GetNextInsertionPosition(LogicalDirection ): Start from richTextBox1.Selection.Start and move towards the beginning of the line (char != '\n')
I've needed to figure out when I was on the top line or bottom line of the RTB. To do this I used the GetCharacterRect methods then compared the tops to see if it was on the last line or first line.
You could do the same and use a text pointer to move through the text and number of times the tops don't match.
Here's code to see if the cursor is on the first or last lines:
private bool IsCursorOnFirstLine()
{
TextPointer contentStart = this.ContentStart;
TextPointer selection = this.Selection.End;
Rect startRect = contentStart.GetCharacterRect(LogicalDirection.Forward);
Rect endRect = selection.GetCharacterRect(LogicalDirection.Forward);
return startRect.Top == endRect.Top;
}
private bool IsCursorOnLastLine()
{
TextPointer start = this.Selection.Start;
TextPointer end = this.ContentEnd;
Rect startRect = start.GetCharacterRect(LogicalDirection.Forward);
Rect endRect = end.GetCharacterRect(LogicalDirection.Backward);
return startRect.Top == endRect.Top;
}