简体   繁体   English

如何根据用户控件上的属性设置来设置用户控件中元素的大小?

[英]How do I set the size of elements in a user control according to property settings on the user control?

To make this simple: I have a user control that consists of 2 rectangles. 简单起见:我有一个由2个矩形组成的用户控件。 At design time the user of the control sets the width of the user control and a default value for one of the rectangles which is a property of the user control. 在设计时,控件的用户设置用户控件的宽度和矩形之一的默认值,这是用户控件的属性。 I want to treat the default value as a percentage and set the width of one of the rectangles to that percentage of the other rectangles width. 我想将默认值视为百分比,然后将其中一个矩形的宽度设置为其他矩形宽度的百分比。 The kind of difficulty I'm having is that I cannot get the width of the outer rectangle to set the other rectangles width as a percentage of (because everything seems to be 0 or NaN). 我遇到的一种困难是,我无法获取外部矩形的宽度来将其他矩形的宽度设置为百分比(因为所有内容似乎都是0或NaN)。 Here's some code: 这是一些代码:

User Control: 用户控制:

<Grid x:Name="LayoutRoot" Background="White">

    <Rectangle x:Name="OuterRectangle" Fill="Red"/>
    <Rectangle x:Name="InnerRectangle" Fill="Blue"/>

</Grid>

User Control code behind: 后面的用户控制代码:

public partial class ucRectangles : UserControl
{
    public Double Percent { get; set; }

    public ucRectangles()
    {
        InitializeComponent();

        InnerRectangle.Width = Percent / 100 * OuterRectangle.ActualWidth;
    }
}

Main Page: 主页:

<Grid x:Name="LayoutRoot" VerticalAlignment="Center">

    <local:ucRectangles Width="400" Height="40" Percent="50"/>

</Grid>

Why don't you get the Grid to do all this for you that is what its good at:- 您为什么不让Grid为您完成所有这一切呢?

<Grid x:Name="LayoutRoot" Background="White">
     <Grid.ColumnDefinitions>
         <ColumnDefinition Width="50*" />
         <ColumnDefinition Width="50*" />
     </Grid.ColumnDefinitions>
     <Rectangle x:Name="OuterRectangle" Fill="Red" Grid.ColumnSpan="2"/>
     <Rectangle x:Name="InnerRectangle" Fill="Blue" />
</Grid>

Now just fiddle with the star values of the column definitions, here is my implementation of the Percent dependency property:- 现在只是摆弄列定义的星号,这是我对Percent依赖项属性的实现:

    #region public double Percent
    public double Percent
    {
        get { return (double)GetValue(PercentProperty); }
        set { SetValue(PercentProperty, value); }
    }

    public static readonly DependencyProperty PercentProperty =
        DependencyProperty.Register(
            "Percent",
            typeof(double),
            typeof(ShowCase1),
            new PropertyMetadata(50.0, OnPercentPropertyChanged));

    private static void OnPercentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ShowCase1 source = d as ShowCase1;
        double percent = (double)e.NewValue;

        source.LayoutRoot.ColumnDefinitions[0].Width = new GridLength(percent, GridUnitType.Star);
        source.LayoutRoot.ColumnDefinitions[1].Width = new GridLength(100 - percent, GridUnitType.Star);            
    }
   #endregion public double Percent

Note its the last two lines where the magic happens. 注意魔术发生的最后两行。

I know this seems answered already, but here's something similar I did last year for creating simple bar charts. 我知道这似乎已经回答了,但是这与我去年创建简单条形图时所做的类似。 Just bind your percentage to the "Content" property and you'll get a auto-resizing bar without all the extra code... 只需将百分比绑定到“ Content”属性,您将获得一个自动调整大小的栏,而无需所有额外的代码...

<ContentPresenter Content="0.3" Height="30">   <!-- Bind the "Content" to your percentage -->
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <Grid Background="YellowGreen">
                    <Rectangle Fill="Purple" Margin="0,5,0,5" HorizontalAlignment="Stretch" RenderTransformOrigin="0.5,0.5">
                        <Rectangle.OpacityMask>
                            <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                                <GradientStop Color="#FFFFFFFF" Offset="0"/>
                                <GradientStop Color="#FFFFFFFF" Offset="{Binding}"/>
                                <GradientStop Color="#00000000" Offset="{Binding}"/>
                                <GradientStop Color="#00000000" Offset="1"/>
                            </LinearGradientBrush>
                        </Rectangle.OpacityMask>
                    </Rectangle>
                </Grid>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>

ActualWidth would only be relevant after the Measure pass has taken place. ActualWidth仅在进行度量传递之后才有意义。 You're trying to do it in the C-tor, which would be WAY before the Measure is happening. 您正在尝试在C-tor中执行此操作,这可能是在实施该措施之前。

Try and use the Event LayoutUpdated, which is bound to happen after the layout process finished. 尝试使用事件LayoutUpdated,它肯定会在布局过程完成之后发生。

Handle (user control's) LayoutRoot's loaded event and move code inside it. 处理(用户控件)LayoutRoot的已加载事件,并在其中移动代码。

User Control XAML 用户控件XAML

   <Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">

User Control Code Behind 背后的用户控制代码

 private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
    {
        InnerRectangle.Width = Percent / 100 * OuterRectangle.ActualWidth;
    }

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM