WPF ScrollViewer为我的listview(在网格行中)提供整个屏幕而不是一部分

时间:2014-08-15 19:28:44

标签: wpf xaml scrollviewer

我的usercontrol上的主网格有3行。顶行是一个数据绑定的listvew,占整个窗口的60%左右(可显示的数据行数量更多,listview自动显示滚动条 - 这很好)。第二行是网格分析器,第三行占用显示器的其余部分。

此第3行有一个包裹在边框中的网格,还包含一个包装文本框。可以变得更大。当它这样做时,它有时会将按钮推到屏幕的最底部,所以我想如果我在主网格周围包裹一个ScrollViewer,我会在屏幕上以与现有listview滚动条相同的比例保留我的3行保持原样,然后只需在右侧获得一个额外的滚动条,如果第三行变得太高,我可以向下滚动查看按钮(就像你在这个浏览器页面上做的那样,滚动条代码和页面滚动条也是如此)。

相反的是,列表视图的第一行已经垂直扩展以占据整个屏幕,直到我滚动到列表视图中所有项目的末尾才能看到第2行或第3行。我尝试了各种硬编码行高(不好,我知道)'自动'和& '*'现在可以利用。

有没有办法完成我正在尝试的东西?我不认为我必须(并且不想)重新设计整个屏幕。

谢谢,我是WPF&的新手。它有趣但有时非常令人沮丧!

我在下面发布了一些XAML,但我不确定它会有所帮助。

 <ScrollViewer>
    <Grid Name="grdEvents" HorizontalAlignment="Center" >
    <Grid.RowDefinitions>
        <RowDefinition Height="60*" />
        <RowDefinition Height="10" />
        <RowDefinition Height="30*"/>
    </Grid.RowDefinitions>
    <ListView SelectionChanged="lvActivities_SelectionChanged" MouseDoubleClick="ListView_MouseDoubleClick" Grid.Row="0" Name="lvActivities" HorizontalAlignment="Stretch" LVLO:ListViewLayoutManager.Enabled="True" >
        <!--ItemContainerStyle="{StaticResource SelectedItem}"   MouseEnter="lvActivities_MouseEnter"  -->

        <ListView.ItemContainerStyle>
            <Style TargetType="ListBoxItem">

...

   </ListView>


    <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch">  </GridSplitter>

    <Border Grid.Row="2" CornerRadius="20" 
            BorderBrush="Gray"
            Background="White"
            BorderThickness="2"
            Padding="8">

        <Grid Name="wpCurrentRow" DataContext="{Binding ElementName=lvActivities, Path=SelectedItem}" Grid.Row="2" Background="{StaticResource ResourceKey=MyBackGroundBrush}">

2 个答案:

答案 0 :(得分:1)

我认为你不能用相对的行大小来完成你想要的东西。但是,只要ScrollViewer的大小发生变化,您可以手动设置与顶行成比例的高度。但是,由于您还有一个分离器,一旦用户手动调整高度,您将需要停止这样做。看看这个:

XAML:

<Window x:Class="StackOverflow.Wpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>
    <ScrollViewer x:Name="_scrollViewer">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition x:Name="_mainRow" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <ListView />

        <GridSplitter x:Name="_splitter"
                      Grid.Row="1"
                      Height="5"
                      HorizontalAlignment="Stretch"
                      ResizeDirection="Rows"
                      ResizeBehavior="PreviousAndNext"
                      MouseDoubleClick="OnSplitterMouseDoubleClick" />

        <Grid Grid.Row="2" />
      </Grid>
    </ScrollViewer>
  </Grid>
</Window>

代码背后:

public partial class MainWindow
{
    private bool _shouldUpdateGridLayout;

    public MainWindow()
    {
        InitializeComponent();
        EnsureGridLayoutUpdates();
    }

    private void EnsureGridLayoutUpdates()
    {
        if (_shouldUpdateGridLayout)
            return;

        _scrollViewer.SizeChanged += OnScrollViewerSizeChanged;
        _splitter.DragCompleted += OnSplitterDragCompleted;
        _shouldUpdateGridLayout = true;
    }

    private void CancelGridLayoutUpdates()
    {
        if (!_shouldUpdateGridLayout)
            return;

        _scrollViewer.SizeChanged -= OnScrollViewerSizeChanged;
        _splitter.DragCompleted -= OnSplitterDragCompleted;
        _shouldUpdateGridLayout = false;
    }

    private void UpdateGridLayout()
    {
        _mainRow.Height = new GridLength(2 * _scrollViewer.ActualHeight / 3);
    }

    private void OnScrollViewerSizeChanged(object s, SizeChangedEventArgs e)
    {
        UpdateGridLayout();
    }

    private void OnSplitterDragCompleted(object s, DragCompletedEventArgs e)
    {
        CancelGridLayoutUpdates();
    }

    private void OnSplitterMouseDoubleClick(object s, MouseButtonEventArgs e)
    {
        EnsureGridLayoutUpdates();
        UpdateGridLayout();

        // Handle the event to prevent DragCompleted from being raised
        // in response to the double-click.
        e.Handled = true;
    }
}

请注意,当用户双击拆分器时,我选择恢复默认大小和自动大小管理。它不是最漂亮的解决方案,但它使用固定的高度。随意将行为封装在自定义面板/控件中。

答案 1 :(得分:0)

不使用比例,而是在行上使用硬编码高度。将第一行的60 *更改为60。

同样只是为了实验,你可以试试这个:

<Grid.RowDefinitions>
    <RowDefinition Height="2*"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Name="ListBox1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Grid.Row="0" Background="Blue"/>
<ScrollViewer Grid.Row="1">
    <StackPanel >   
        <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click" />
        <TextBox>Hello </TextBox>
    </StackPanel>
</ScrollViewer>

它向第二行添加了一个滚动查看器,然后使用堆栈面板存储其余元素。它也让它看起来更好。

仅添加了元素;用你自己的替换它们。