I'm using Silverlight 3/C#, and I'm trying to create some XAML objects programatically in response to a user clicking on a button.
However, I can't seem to position a Canvas
object that I have created - when I call SetValue()
on the new Canvas
with the Canvas.LeftProperty
value, the browser window clears to an empty screen.
I have a simple function that exhibits the problem (I started out with something more complex):
private Canvas MakeNewCanvas()
{
Canvas newCanvas = new Canvas();
newCanvas.Width = newCanvas.Height = 50;
newCanvas.SetValue(Canvas.LeftProperty, 10);
return newCanvas;
}
and a simple button click handler that calls this:
private void MyButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
myPage.Children.Add(MakeNewCanvas());
}
NB: myPage is a Canvas object defined in my app's MainPage XAML file.
I've traced this through in the VS debugger with the SL app executing in Firefox, and whenever it executes the SetValue()
line, the browser goes white and starts trying to download data (according to the status bar). I tried calling SetValue()
after I've put the Canvas
in the XAML tree with something like:
myPage.Children.Add(newCanvas);
newCanvas.SetValue(Canvas.LeftProperty, 10);
but it makes no difference - as soon as the SetValue()
call is hit, the browser goes white.
The Canvas
class seems to have no direct method of setting Left/Top on itself, apart from the SetValue()
function with dependency property enum values. There's also Canvas.SetLeft()
and Canvas.SetTop()
but I guess they're just shims onto SetValue()
. Using them didn't help anyway.
If I don't call SetValue()
, then my canvas appears (and child objects I've added to it) in the SL app as you might expect, in the very top left.
If I create and position a Canvas
object in Expression Blend, then the XAML generated includes Canvas.Left
and Canvas.Top
property values on the Canvas
itself, as I would expect, so it seems to me that what I'm trying in C# should work.
But I don't seem to be able to set the left/top values myself from C# without the SL in the browser going all weird.
Any ideas?
Edit: my approach is correct, but canvas coords need to be floating point, not integer - see开发者_运维知识库 accepted answer for details.
Trying your code, but with the debugger catching exceptions, I get:
DependencyProperty of type System.Double cannot be set on an object of type System.Int32.
which is a really stupid gotcha - SetValue only takes Object, so you're prone to a problem like this.
Try either:
newCanvas.SetValue(Canvas.LeftProperty, 10.0);
or
Canvas.SetLeft(newCanvas, 10);
and it will probably work.
The behaviour of attached properties can be a little confusing at first.
The properties Canvas.LeftProperty and Canvas.TopProperty are applied to child objects of a canvas. They are therefore only meaningful when the child object is placed on a Canvas
. Its important to understand the in WPF/SL objects do not position themselves, its up to the containing panel to decide where to put them.
I suspect the myPage
is not of the Canvas
type, its probably a Grid
, hence it would have no idea what to do with such properties even if it bothered to look for them (which it doesn't).
In order for you to specifically position you new Canvas you need to be adding it to a Canvas.
精彩评论