|
Thanks! Worked like a charm!!!
|
|
|
|
|
Cool
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I believe I have found an interesting quirk. I could not get the images in the
WPF application to render in the random position order as shown in the silverlight
example version. A value that in the silverlight version returns valid floating
point values, returns "NaN" in the WPF version. The calculations seem to be the
same, so how can "NaN" be returned for one but not the other? I have modified the
project so that the values of the "NaN" numbers that should be floating point values
are recorded in a file called "Errors.txt".
Go here to see the newly modified file
www.avtinconline.com/Silverlight/ImageSpace3Dwpf.zip
|
|
|
|
|
bdb38865 wrote: Go here to see the newly modified file
Can you just post the relevant calculation code here (the original Silverlight
and the ported WPF code)?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Here is the calculation method. It is the same in silverlight and WPF.
private void posImage()
{
//System.Windows.Forms.MessageBox.Show("HEllo");
for (int i = 0; i < _images.Count; i++)
{
Image image = _images[i];
Point3D point3D = _imagePoint3Ds[image];
double zActual = SPACE_LENGTH + (point3D.z - _camera.z);
double scale = SPACE_LENGTH / zActual - EFFECT_FACTOR;
// update the image position and scale
if (scale > 0)
{
image.SetValue(Canvas.LeftProperty, (point3D.x - _camera.x) * scale);
image.SetValue(Canvas.TopProperty, (point3D.y - _camera.y) * scale);
Log.WriteToLog(image.ToString() +": "+ Convert.ToString((point3D.x - _camera.x) * scale));
ScaleTransform scaleTransform = new ScaleTransform();
scaleTransform.ScaleX = scale * NEW_SCALE;
scaleTransform.ScaleY = scale * NEW_SCALE;
image.RenderTransform = scaleTransform;
image.Opacity = 1 - 0.99 * zActual / SPACE_LENGTH * 0.5;
//image.Opacity = 1;
// sort the children according to the scale
image.SetValue(Canvas.ZIndexProperty, (int)(SPACE_LENGTH - point3D.z));
}
else
{
// if text move over the screen, place it at the back
point3D.z += SPACE_LENGTH * 2;
}
}
|
|
|
|
|
The problem isn't in there.
The ImageSpace3D.addImages() method is where the random calculations are made.
The calculations are based on the Width and Height properties of the control, which
are always NaN unless set somewhere, which they are not.
ActualWidth and ActualHeight are the properties that should be used, and should have been
used in the Silverlight version as well.
ActualWidth and ActualHeight are not set until the control is loaded so you need to call the
initialization code from a "Loaded" event handler (or later) instead of from the constructor.
Here's what you should have to make it work...
<!-- ImageSpace3D.xaml -->
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="ImageSpace3Dwpf.ImageSpace3D"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480"
<code>Loaded="UserControl_Loaded"</code> >
<Grid x:Name="LayoutRoot"/>
</UserControl>
public ImageSpace3D()
{
InitializeComponent();
<code>
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
_holder.SetValue(Canvas.LeftProperty, <code>ActualWidth</code> / 2);
_holder.SetValue(Canvas.TopProperty, <code>ActualHeight</code> / 2);
LayoutRoot.Children.Add(_holder);
addImages();
addImages();
_timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0, 0, 0, 0, 1000 / FPS);
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
<code>
private void addImages()
{
int seed = (int)DateTime.Now.Ticks;
for (int i = 0; i < IMAGES.Length; i++)
{
seed += (int)DateTime.Now.Ticks;
Random r = new Random(seed);
String url = IMAGE_PATH + IMAGES[i];
Image image = new Image();
image.Source = new BitmapImage(new Uri(url, UriKind.Relative));
Point3D point3D = new Point3D();
point3D.x = r.NextDouble() * <code>ActualWidth - ActualWidth</code> / 2;
point3D.y = r.NextDouble() * <code>ActualHeight - ActualHeight</code> / 2;
point3D.z = r.NextDouble() * SPACE_LENGTH * 2 - SPACE_LENGTH;
image.SetValue(Canvas.LeftProperty, point3D.x);
image.SetValue(Canvas.TopProperty, point3D.y);
image.MouseLeftButtonDown += new MouseButtonEventHandler(image_MouseLeftButtonDown);
image.Cursor = Cursors.Hand;
_imagePoint3Ds.Add(image, point3D);
_holder.Children.Add(image);
_images.Add(image);
}
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for you help; however, now I get the following error when I attempt to implement your changes to the XAML for ImageSpace3Dwpf:
Error 1 ''d' is an undeclared namespace. Line 9, position 2.' XML is not valid. C:\Documents and Settings\rDev\My Documents\Expression\Expression Blend Projects\ImageSpace3Dwpf\ImageSpace3Dwpf\ImageSpace3D.xaml 9 2 ImageSpace3Dwpf
|
|
|
|
|
The point is - just add the Loaded event handler.
That's all I changed in the XAML.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Never mind, I got it. Thanks for all your help
|
|
|
|
|
bdb38865 wrote: Thanks for all your help
No problem!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have a button on a ControlTemplate . I want to handle its click events in the control that uses the template. How would I make that happen?
<ControlTemplate x:Key="UDPTemplateTabControlEx" TargetType="{x:Type TabControl}">
<Grid x:Name="Grid" KeyboardNavigation.TabNavigation="Local">
<ScrollViewer x:Name="HeaderPanelEx" Grid.Row="0" Grid.Column="0"...>
<ScrollViewer.Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Margin="0,0,0,0" Grid.Row="0" x:Name="HeaderPanelEx">
<Button Grid.Column="0" Width="25" Content="..." />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
</ScrollViewer>
</Grid>
</ControlTemplate>
I tried putting a name property on it, but I still can't see it in intellisense in the code...
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote:
I did something similar but I used the Command property of the button not the Click event.
<button grid.column="0" width="25" content="..." command="MyCommand" />
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
Individuality is fine, as long as we do it together - F. Burns
Help humanity, join the CodeProject grid computing team here
|
|
|
|
|
John Simmons / outlaw programmer wrote: I want to handle its click events in the control that uses the template. How would I make that happen?
It can also depend on where the template is defined.
If it's in a place backed by code-behind (ie a class) then you can add
an event handler like you would anywhere else.
If the template is in a resource dictionary or some other place without a class
then maybe implementing a command as Wes mentioned would be the way to go.
You can also wire event handlers at runtime, perhaps by overriding OnApplyTemplate()[^] and
using FindName()[^] to find the button instantiated by the template.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I'm not sure about the event stuff in WPF yet. I mean, sure, I'm handling click events from buttons and stuff, but I'm not sure about the routed event thing. I haven't found a decent explanation that also includes a decent example of it either. I'm sure that I should look at the routed event stuff, because I'm making controls public in user controls that I have to handle in the form or user control that hosts them, and it just feels wrong to do that.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote: I'm sure that I should look at the routed event stuff
Yes. Routed Events Overview[^]
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
For me, custom commands are the way to go, also in terms of clean separation of presentation and logic. You can use the CommandParameter property to submit some contextual information.
Edit: I guess you might derive your command from RoutedCommand if you want it to bubble up the tree, which would simplify handling the event in the control that makes use of the template.
NetDrives - Open Source Network Share Management
|
|
|
|
|
You can also simply data bind the Button.Command to an ICommand on located on the DataContext.
This is excactly how MVVM applications work.
You can also assign the delegate for the ClickEvent or the Commmand at run-time. I've see this also.
Another way is to set up an AttachedEvent at a parent object where this button and possibly others grouped. Then just handle the Button.ClickEvent.
All are very acceptable techniques.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
Hello, I can't install the Toolbox from Silverlight because it stops the installation and show me that it has a problem with my InternetExplorer Version 7. Is there a trick, another download or something special that I missed!?!?! Or require the new Silverlight Toolbox InternetExplorer Version 8?!?!?!?.
Thank's for any help
Frank
|
|
|
|
|
Frank Köppel wrote: I can't install the Toolbox from Silverlight
You mean the Silverlight ToolKIT from the Codeplex site?
If so, the one for Silverlight 2 or the one for Silverlight 3 Beta?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hello,
I try to use Silverlight_Tools for Version 2.0 because Version 3 is marked as beta!?!?
May I have to try version 3 as well.
Frank
|
|
|
|
|
Version 2 should be what you want, unless you're going to use the beta.
You can't currently have 2 and 3 on the same dev environment.
Make sure you've installed Visual Studio 2008 SP1 and the Silverlight Tools
for Visual Studio 2008 SP1.
What's the error you get?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank's to all, it was my fault!
I've got it running.
Frank
|
|
|
|
|
|
Hi,
I'm working on an small c# test-application as I'm really new to wpf/xaml coding. The App creates a WPF Window with controls and standard dynamic styles.
Runtime I would like to change the style. I don't want to remove and set another style, but get the current style of the control and change things in c# code behind.
I know how to get the style, add new Setter or trigger and remove and the style and add a new style.
What I couldn't find out, if it is possible, is how to change the property values of the given style.
Example: I have an Window with a given "Width" of 600. Now I want to change the width to 300. I could do it in c# I know, but I would like to chagne the given style. Background is, that I would like to save the style in an file and reload it later..
Some Code:
XAML
<br />
<style x:key="MyWindowStyle" targettype="Window" xmlns:x="#unknown"><br />
<setter property="Width" value="600" /><br />
<setter property="Height" value="300" /><br />
</style><br />
C#
<br />
public void SetFirstTemplate()<br />
{<br />
<br />
MyWindowStyle = ((Style)this.Resources["MyWindowStyle"]);<br />
<br />
<br />
}<br />
Has someone experience with that?
|
|
|
|
|