2009-08-31 107 views
3

背景:WPF:如何重置/重新计算的ScrollViewer “ScrollableHeight”

我产生了设置页面的用户界面。这些设置存储在字典中,因为每个对象的设置都会有所不同。

问题:

一个ScrollViewerScrollableHeight不是acurate的所述内容的尺寸。当ScrollViewer的内容发生更改时ScrollableHeight未被重置,而是追加新内容的高度。

当:

我一个Grid,这是ScrollViewer内的子元素中产生的内容。内容为RowDefinitions,其中名称 - 值对显示为TextBlocksTextBoxes。当为了编辑其属性而选择不同的对象时,网格的子项被清除,并且用于显示属性的UI被重新生成。正如我之前在问题定义中提到的,生成的内容的高度被附加到ScrollViewerScrollableHeight属性中。

我学到的东西:

我首先想到的是要清除ScrollViewerScrollableHeight和用于增加追加行的高度,以达到正确的大小每一行。问题是无法设置ScrollableHeight(私人设置者)。

代码:

XAML:

<ScrollViewer Name="svScroller" Grid.Row="0"> 
    <Grid x:Name="gdPropertyGrid" Margin="10"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="35*" /> 
      <ColumnDefinition Width="65*" /> 
     </Grid.ColumnDefinitions> 
    </Grid> 
</ScrollViewer> 

C#:

//Get Selected Item 
var listBox = ((ListBox)sender); 
var provider = listBox.SelectedItem as IProviderConfiguration; 

if (provider != null) 
{ 
    tbTitle.Text = String.Format("Properties for {0}",provider.Name); 

    int rowCount = 0; 

    PropertyGrid.Children.Clear(); 

    //Get properties 
    foreach (var property in provider.Properties) 
    { 
     //Create Grid Row 
     var rowDef = new RowDefinition() {Height = new GridLength(30)}; 
     PropertyGrid.RowDefinitions.Add(rowDef); 

     //Create Name Label 
     var tbPropertyName = new TextBlock { 
       Text = property.Key, 
       VerticalAlignment = VerticalAlignment.Center 
     }; 

     //Create Value input 
     var tbPropertyValue = new TextBox { 
       Text = property.Value.ToString(), 
       VerticalAlignment = VerticalAlignment.Center 
     }; 

     //Add TextBlock & TextBox Grid 
     PropertyGrid.Children.Add(tbPropertyName); 
     PropertyGrid.Children.Add(tbPropertyValue); 

     //Set Grid.Row Attached property 
     Grid.SetRow(tbPropertyName, rowCount); 
     Grid.SetRow(tbPropertyValue, rowCount); 

     Grid.SetColumn(tbPropertyValue, 1); 

     rowCount++; 
    } 

} 
+0

我会建议使用ListBox和DataTemplate,这比使用ScrollViewer和Grid更容易,你必须扰乱后面的代码。 – user7116 2009-08-31 13:06:35

+0

同意,带有DataTemplate的ListBox确实可以提供优雅的解决方案。上述解决方案的目的是为了开发一个屏幕,该屏幕可以“匹配”网格中TextBlock TextBox对的其他屏幕。但是,你可以用DataTemplate实现这一点。我从来都不喜欢在C#中实现UI,因为它应该在XAML中。 如果情况发生变化,我会开发一个完整的PropertyGrid控件,或者使用像我看到的适合的开源实现,例如http://www.codeplex.com/wpg。谢谢 – holsee 2009-08-31 13:58:38

回答

2

这是ScrollViewer.ScrollableHeight预期的行为,从MSDN:

获取一个表示可以滚动的内容元素的垂直大小的值。

也许您在寻找ScrollViewer.ViewPortHeight?或者你可能正在寻找ScrollViewer,直到滚动前的某个点。在这种情况下,您需要查看另一个解决方案。

编辑

该错误是你不清除RowDefinitions,因此ScrollableHeight总是出现被附加到,因为你不断地添加新行!我的建议是你切换到使用另一个列表框,并与主 - 细节模式。

+0

元评论:ScrollableHeight应该等于Grid.ActualHeight。你可以用Snoop来验证。 – user7116 2009-08-31 13:05:14

+0

为了澄清,答案是“错误是你没有清除RowDefinitions”。谢谢 – holsee 2009-08-31 13:45:38

0

我同意@sixlettervariables,从您对问题的描述,它听起来像你试图做一些错误的属性。我并不清楚你的期望结果是什么,但是我假设你希望能够在同一个滚动查看器中拥有不同数量的项目,并根据需要扩展它以在运行时尽可能多地显示。

ScrollViewer.ViewPortHeight允许您设置可见区域并且是一个读/写属性,并且当内容太大而无法放入可见区域时,滚动条会自动出现(默认情况下)。