C# \ WPF : Problème de ratio dans un canvas.
Bonjour à tous.
Je suis entrain de développer une application qui permet d'afficher le fuselage d'un avion. Le problème est que le dessin contenue dans le canvas conserve pas du tout les bonnes proportions.
Pourriez-vous m'éclairer sur mon erreur.
Je vous en remercie par avance.
Le code vu du xaml :
Code:
1 2 3 4 5 6 7 8 9 10
| <Grid Name="rootGrid" Margin="0">
<Grid x:Name ="chartGrid" Grid.Column="0" Grid.Row="0"
ClipToBounds="True" Background="Transparent" SizeChanged="chartGrid_SizeChanged" />
<Canvas x:Name="chartCanvas" MouseLeftButtonDown="OnMouseLeftButtonDown" ClipToBounds="True">
<Canvas.RenderTransform>
<ScaleTransform x:Name="myScaler" ScaleX="1" ScaleY="1" CenterX="0" CenterY="0"/>
</Canvas.RenderTransform>
</Canvas>
</Grid> |
Le code de l'évènement SizeChanged :
Code:
1 2 3 4 5
| private void chartGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.chartCanvas.Width = this.chartGrid.Width;
this.chartCanvas.Height = this.chartGrid.Height;
} |
Le code qui calcule la position du point par rapport à la taille du canvas :
Code:
1 2 3 4 5 6 7
| public Point NormalizePoint(Point pt)
{
Point result = new Point();
result.X = (pt.X - Xmin) * ChartCanvas.Width / (Xmax - Xmin);
result.Y = ChartCanvas.Height - (pt.Y - Ymin) * ChartCanvas.Height / (Ymax - Ymin);
return result;
} |
"scaler" les objets dans un canvas
bonjour,Julien board ,comme le grand julius ceasar,
"le plus terrible est le plus petit d'entre eux" (proverbe arabe).
Il me semble que c'est l'approche inverse qu'il faut faire .C'est plutot zoomer dans le canvas auquel il faut penser,comme ca tu y mettras les fuselages de 2A380 ,parce que l'approche en matiere de dessin 2d ou 3d c'est toujours mettre les dimensions des objets en unites de bases (point ou pixel ) non lies aux dimensions du controle utilise ( convertir en millimetres pour le papier eventuellement).
Mais il n'est pas question de s'imposer des contraintes en unites de dessin,a cause des dimensions d'un canvas(ou d'un ecran autrement).
Il faut savoir aussi une chose comme l'a dit notre ami ,que le canvas a part defaut une largeur et hauteur indefinie.
Dans tous les cas de figure je t'envoie ci-apres le code d'un "zoomable canvas" qui je l'espere t'aideras:
- derivee simplement du canvas
- avec 1 methode override ,cet override mets les dimensions du canvas assez juste pour contenir tous les objets inclus dans celui (quelque soit le total des dimensions).Ca devient un "viewport":
-a l'utilisation on le droppe dans un scrollviewer et on ajoute un slider
-ScaleX et ScaleY du canvas sont bindes a valeur du slider(trackbar)
caramba !
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
/// code du custom canvas
using System;
using System.Windows;
using System.Windows.Controls;
namespace ZoomCanvas
{
public class ZoomableCanvasControl : Canvas
{
static ZoomableCanvasControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(ZoomableCanvasControl),
new FrameworkPropertyMetadata(
typeof(ZoomableCanvasControl)));
}
protected override Size MeasureOverride(
Size constraint)
{
double bottomMost = 0d;
double rightMost = 0d;
// Loop through the child FrameworkElements,
// and track the highest Top and Left value
// amongst them.
foreach(object obj in Children)
{
FrameworkElement child = obj as FrameworkElement;
if(child != null)
{
child.Measure(constraint);
bottomMost = Math.Max(
bottomMost,
GetTop(child) +
child.DesiredSize.Height);
CHAPTER 4 ■ CREATING USER AND CUSTOM CONTROLS 223
rightMost = Math.Max(
rightMost,
GetLeft(child) +
child.DesiredSize.Width);
}
}
if(double.IsNaN(bottomMost)
|| double.IsInfinity(bottomMost))
{
bottomMost = 0d;
}
if(double.IsNaN(rightMost)
|| double.IsInfinity(rightMost))
{
rightMost = 0d;
}
// Return the new size
return new Size(rightMost, bottomMost);
}
}
} |
code du winform utilisant le canvas:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
<Window x:Class="ZoomCanvas.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:ZoomCanvas;assembly="
Title="WPF canvas " Height="300" Width="300" >
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="24" />
</Style>
</Window.Resources>
<DockPanel>
<Slider
DockPanel.Dock="Bottom"
x:Name="zoomSlider"
Minimum="0.1"
Maximum="5"
Value="1"
/>
<ScrollViewer
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<test:ZoomableCanvasControl x:Name="zoomControl">
<Canvas.LayoutTransform>
<ScaleTransform
ScaleX="{Binding Path=Value, ElementName=zoomSlider}"
ScaleY="{Binding Path=Value, ElementName=zoomSlider}"
/>
</Canvas.LayoutTransform>
<Rectangle
Canvas.Top="0"
Canvas.Left="0"
StrokeThickness="2"
Stroke="Red"
Width="50"
Height="50"
/>
<Rectangle
Canvas.Top="50"
Canvas.Left="50"
StrokeThickness="2"
Stroke="Blue"
Width="150"
Height="150"
/>
<Rectangle
Canvas.Top="200"
Canvas.Left="200"
StrokeThickness="2"
Stroke="Green"
Width="200"
Height="200"
/>
</test:ZoomableCanvasControl>
</ScrollViewer>
</DockPanel>
</Window> |
Lux fat...Alea Jacta est aurais dit un romain il y a 1600 ans ...
Les lumieres de l'esprit n'ont pas d'epoque ni de contrees....
J'aime lire l'histoire ,j'ai la conquete des gaules dans ma biblio et la republique de Ciceron.
Bon soiree et bonne fete de noel....