【问题标题】:C# WPF Resizing elemens by CodeC# WPF 通过代码调整元素大小
【发布时间】:2017-02-08 13:18:06
【问题描述】:

我仍在使用我的工具。 我即将使调整大小成为可能。在这种情况下,我试图使时钟的标签可调整大小。 XAML 代码如下所示:

  <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"/>

要调整它的大小,我将使用这个 C# 代码:

   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);


    }

它会起作用,但是单独修改每个 Item 非常难看。我试图修改矩形的高度和宽度以及标签的字体大小,如下所示:

    <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>

但我不知道如何在代码中访问“recWidth”、“recHeight”和“fontSize”。任何人都可以帮助我吗?任何人都有清理代码的想法吗?

谢谢:)

截图 Whole ClockThing Labeling

【问题讨论】:

  • WPF 为我们带来了精彩的布局系统(here 是对相关问题的一个很好的解释)。您能解释一下为什么要使用Margin 来进行微不足道的调整大小吗?如果您坚持必须这样做,那么添加屏幕截图可能会有所帮助。
  • 要调整大小,请将整个时钟放在 Viewbox 中。
  • 您不能在代码中修改密封样式设置器的值。为什么你甚至需要访问“recWidth”、“recHeight”和“fontSize”设置器?
  • @Sinatr 我从来没有学过处理 WPF,我只是一个有工作的学生 :) 我添加了 2 个屏幕截图 :)
  • @Clemens 我会试试这个谢谢:)

标签: c# wpf visual-studio xaml .net-4.0


【解决方案1】:

我已经简化布局(实际上可以是矢量图形中的一行)到固定大小的容器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>

ViewBox 中托管某些内容时,它将自动缩放(Grid 将按比例调整大小),无需手动更改任何内容。

这是一个演示:

【讨论】:

  • 对我来说工作得很好,让代码看起来更干净 :) 再次感谢 :)
【解决方案2】:

如果您希望将以下隐式样式应用于UserControl 中的所有LabelsRectangles

<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>

...您应该设置UserControl 中元素的任何这些属性,无论是在XAML 标记中还是在代码中。如果你这样做:

label12.FontSize = fontSize;

...本地值 (fontSize) 将优先于样式设置器设置的值:https://msdn.microsoft.com/en-us/library/ms743230(v=vs.110).aspx

我需要更改这些值...

然后您可以在 UserControl 中定义源属性并绑定到这些属性:

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>

代码:

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));
    }
}

【讨论】:

  • 是的,这就是我的问题。我需要更改这些值。但我无法访问样式,所以我必须在代码中设置所有属性以防调整大小。我只是想改变风格,所以我不必为每个标签都改变它:)
  • 然后您可以在 UserControl 中定义源属性并绑定到这些属性。请参阅我编辑的答案。
  • 谢谢。我可以使用它让用户选择模块的颜色:)
猜你喜欢
  • 2011-09-08
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多