Reputation: 285
I still working on my Tool. I'm about to make resizing possible. In this case I'm trying to make the labeling of a clock resizable. The XAML Code looks like:
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label x:Name="label12" Content="12" Margin="0,0,138,103" Grid.ColumnSpan="2" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
<Rectangle x:Name="rec1" Margin="0,0,85,97" Grid.Column="1" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="30"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="rec2" Margin="0,0,44,54" Grid.Column="1" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="60"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Label x:Name="label3" Content="3" Margin="0,0,19,137" Grid.Column="1" Grid.RowSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
<Rectangle x:Name="rec4" Margin="0,0,47,85" Grid.Column="1" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="120"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="rec5" Margin="0,0,88,44" Grid.Column="1" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="150"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Label x:Name="label6" Content="6" Margin="0,0,135,21" Grid.ColumnSpan="2" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
<Rectangle x:Name="rec7" Margin="0,0,60,45" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="210"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="rec8" Margin="0,0,102,88" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="240"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="rec10" Margin="0,0,102,55" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="300"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="rec11" Margin="0,0,59,99" Width="3" Height="7" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="330"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Label x:Name="label9" Content="9" Margin="0,0,103,137" Grid.RowSpan="2" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
To Resize it I will use this C#-Code:
public void resizeMe()
{
double fontSize = WPFView.getInstance().ActualHeight / (300 / 12.0);
label12.FontSize = fontSize;
label3.FontSize = fontSize;
label6.FontSize = fontSize;
label9.FontSize = fontSize;
double recHeight = WPFView.getInstance().ActualHeight / (300 / 7.0);
double recWidth = WPFView.getInstance().ActualHeight / (300 / 3.0);
rec1.Height = recHeight;
rec1.Width = recWidth;
rec2.Height = recHeight;
rec2.Width = recWidth;
rec4.Height = recHeight;
rec4.Width = recWidth;
rec5.Height = recHeight;
rec5.Width = recWidth;
rec7.Height = recHeight;
rec7.Width = recWidth;
rec8.Height = recHeight;
rec8.Width = recWidth;
rec10.Height = recHeight;
rec10.Width = recWidth;
rec11.Height = recHeight;
rec11.Width = recWidth;
double marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 103.0);
double marginRight = (WPFView.getInstance().ActualHeight) / (300 / 138.0);
label12.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight ) / (300 / 97.0);
marginRight = (WPFView.getInstance().ActualHeight ) / (300 / 85.0);
rec1.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 54.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 44.0);
rec2.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 137.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 19.0);
label3.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 85.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 47.0);
rec4.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 44.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 88.0);
rec5.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 21.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 135.0);
label6.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 45.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 60.0);
rec7.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 88.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 102.0);
rec8.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 137.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 103.0);
label9.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 55.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 102.0);
rec10.Margin = new Thickness(0, 0, marginRight, marginBottom);
marginBottom = (WPFView.getInstance().ActualHeight) / (300 / 99.0);
marginRight = (WPFView.getInstance().ActualHeight) / (300 / 59.0);
rec11.Margin = new Thickness(0, 0, marginRight, marginBottom);
}
It will work, but its pretty ugly to modify every single Item by itself. I tried to modify the Height and Width of the Rectangles and the FontSize of the Lables like this:
<UserControl.Resources>
<Style TargetType="Label" x:Name="labelStyle">
<Setter x:Name="fontSizeSetter" Property="FontSize" Value="12"></Setter>
<Setter x:Name="fontColor" Property="Foreground" Value="White"></Setter>
</Style>
<Style TargetType="Rectangle" x:Name="rectangleStyle">
<Setter Property="Fill" Value="White"></Setter>
<Setter x:Name="recWidth" Property="Width" Value="3"></Setter>
<Setter x:Name="recHeight" Property="Height" Value="7"></Setter>
</Style>
</UserControl.Resources>
But i dont know how to access "recWidth", "recHeight" and "fontSize" in Code. Anyone can help me? And anoyone got an any ideas to clean the code?
Thanks :)
Screenshots Whole ClockThing Labeling
Upvotes: 0
Views: 336
Reputation: 21969
I've simplified layout (it can be actually just one line in vector graphics) into container of fixed size 100,100
:
<Viewbox>
<!-- container for everything, notice fixed size, all position inside are relative to it -->
<Grid Width="100" Height="100">
<Grid.Resources>
<!-- to avoid repeating properties we can use style -->
<Style TargetType="TextBlock">
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="FontSize" Value="8" />
</Style.Setters>
</Style>
<Style TargetType="Rectangle">
<Style.Setters>
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="3" />
<Setter Property="Height" Value="7" />
<Setter Property="Stroke" Value="Black" />
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
</Style.Setters>
</Style>
</Grid.Resources>
<!-- uncomment Ellipse and Line to be able to correctly position other elements -->
<!-- change Angle to position other elements: 0, 30, 60, etc. -->
<!--<Ellipse Stroke="Black" />
<Line X2="100"
Y1="50"
Y2="50"
Stroke="Black"
RenderTransformOrigin="0.5,0.5">
<Line.RenderTransform>
<RotateTransform Angle="0" />
</Line.RenderTransform>
</Line>-->
<TextBlock Text="12" Margin="46,0,0,0" />
<TextBlock Text="6" Margin="48,89,0,0" />
<TextBlock Text="3" Margin="93,44,0,0" />
<TextBlock Text="9" Margin="3,44,0,0" />
<Rectangle Margin="27,9,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="-30" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="11,25,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="-60" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="11,68,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="-120" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="27,84,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="-150" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="70,9,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="30" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="86,25,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="60" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="86,68,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="120" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Margin="70,83,0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="150" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Viewbox>
When something is hosted inside ViewBox
it will get autoscaled (Grid
will be proportionally resized), there is no need to manually change anything.
Here is a demo:
Upvotes: 1
Reputation: 169150
If you want the following implicit styles to get applied to all Labels
and Rectangles
in the UserControl
:
<UserControl.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="12"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="White"></Setter>
<Setter Property="Width" Value="3"></Setter>
<Setter Property="Height" Value="7"></Setter>
</Style>
</UserControl.Resources>
...you should not set the any of these properties of the elements in the UserControl
, neither in the XAML markup nor in code. If you do this:
label12.FontSize = fontSize;
...the local value (fontSize
) will take precedence over the value set by the style setter: https://msdn.microsoft.com/en-us/library/ms743230(v=vs.110).aspx
I need to change these Values ...
Then you could define source properties in your UserControl and bind to these:
XAML:
<UserControl x:Class="WpfApplication3.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="{Binding TheFontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"></Setter>
<Setter Property="Foreground" Value="{Binding TheForeground, RelativeSource={RelativeSource AncestorType=UserControl}}"></Setter>
</Style>
</UserControl.Resources>
<Grid>
<Label Content="Test" />
</Grid>
</UserControl>
Code:
public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
public UserControl1()
{
InitializeComponent();
Loaded += (s, e) => resizeMe();
}
public void resizeMe()
{
TheFontSize = 40.0;
TheForeground = Brushes.Red;
}
private double _fontSize;
public double TheFontSize
{
get { return _fontSize; }
set { _fontSize = value; OnPropertyChanged(); }
}
private Brush _foreGround;
public Brush TheForeground
{
get { return _foreGround; }
set { _foreGround = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 0