2011-03-31 68 views
1

为了简单起见:我有一个由2个矩形组成的用户控件。在设计时,控件的用户设置用户控件的宽度和用户控件属性的其中一个矩形的默认值。我想将默认值作为百分比,并将其中一个矩形的宽度设置为其他矩形宽度的百分比。我遇到的困难是我无法获得外部矩形的宽度来设置其他矩形宽度的百分比(因为一切似乎都是0或NaN)。下面是一些代码:如何根据用户控件上的属性设置来设置用户控件中元素的大小?

用户控制:

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

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

</Grid> 

用户控件后台代码:

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

    public ucRectangles() 
    { 
     InitializeComponent(); 

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

主页:

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

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

</Grid> 

回答

1

你为什么不拿到网格做这一切为你那就是它擅长的: -

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

现在只是拨弄列定义的明星价值,这是我实现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 

注意它的最后两行,其中魔术发生。

0

ActualWidth的只会是相关的测量通有后发生在。你正试图在C-tor中做到这一点,在度量发生之前这将是WAY。

尝试并使用布局过程完成后发生的Event LayoutUpdated。

+1

好吧,这工作,但我只需要它来运行一次,在启动时,而不是每次浏览器调整大小或(无论其他)我是否在处理程序本身中分离处理程序。这是好的做法吗?有什么影响吗? – descf 2011-03-31 19:07:54

+0

这很合理,并且没有任何影响。只需删除处理程序。 – 2011-03-31 19:09:20

0

处理(用户控件的)LayoutRoot的加载事件并在其中移动代码。

用户控制XAML

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

用户控件代码隐藏

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

enter image description here

+0

OuterRectangle.ActualWidth仍然在零 – descf 2011-03-31 18:56:19

+0

不,它不..看到上面的图片..你确定你正确地处理事件,并有该事件内的代码? – 2011-03-31 19:06:54

+0

我仔细检查了我的代码,以确保它与您的代码相同,而且我仍然收到零。 – descf 2011-03-31 19:10:01

0

我知道这似乎已经回答了,但这里的东西类似于去年创建简单的条形图。只要您的百分比绑定到“内容”属性,你会得到一个自动调整大小酒吧都没有额外的代码...

<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> 
相关问题