如何使scrollviewer在这种情况下工作?

时间:2014-10-07 09:58:28

标签: c# wpf mvvm scrollviewer

我的MVVM应用程序遇到一些问题。 所以场景如下:

  • 在我的MainWindow.xaml中,我将一个ContentControl放在一个Grid Column中,它的内容绑定到CurrentViewModel,它将呈现给相应的View(在本例中为Overview.xaml)。

            <ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding CurrentViewModel}">
    
  • 在此特定视图(Overview.xaml)中,StackPanel中放置了多个UserControl。

    <ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
    <StackPanel CanVerticallyScroll="True" CanHorizontallyScroll="True">
        <views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
        <views:IncomeCollectionView DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
        <views:ExpenseCollectionView DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
        <views:CheckCollectionView DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" />
        <views:BalanceCollectionView DataContext="{Binding Path=BalancesViewModel, Source={StaticResource Locator}}" />
        <views:VacationCollectionView DataContext="{Binding Path=VacationsViewModel, Source={StaticResource Locator}}" />
        <views:KHCollectionView DataContext="{Binding Path=KhViewModel, Source={StaticResource Locator}}" />
        <views:OctaviaCollectionView DataContext="{Binding Path=OctaviaViewModel, Source={StaticResource Locator}}" />
    </StackPanel>
    </ScrollViewer>
    
  • 此StackPanel中的每个UserControl都具有非常相似的外观(显然XAML中有更多内容)。 我的应用程序中的宽度或高度没有常数值

            <ListView ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Items[0].CurrentCategory}" />
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="12" Rows="1" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemContainerStyle>
                <Style>
                    <Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding EncryptedAmount}" />
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Got paid on " />
                            <TextBlock Text="{Binding Date}" />
                        </StackPanel>
                        <Button Content="details"
                                Command="{Binding Path=DataContext.ShowDialogCommand,
                                RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
                                CommandParameter="QuickEdit"/>
                        <Button Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    

问题是我似乎无法使垂直滚动查看器工作。显示它是因为我让它可见,但它已被禁用。显然StackPanel会不确定地增长,但是它没有办法计算需要多少空间?因为大部分内容现在都被切断了。 所以我试图将scrollviewer放在每个可能的位置,但它们都被禁用了。

        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <ScrollViewer>
                            <ContentPresenter Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                        </ScrollViewer>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

然后我尝试删除StackPanel实现并尝试使用Grid。 不,它也不起作用。 显然我在这里缺少一些基础解决方案,但是无法弄明白。 任何想法都会受到赞赏,说实话似乎是一种非常普遍的情况。 干杯

    <ScrollViewer CanContentScroll="True"
              VerticalScrollBarVisibility="Visible"
              HorizontalScrollBarVisibility="Visible">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
        <views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
        <views:ExpenseCollectionView Grid.Row="2" DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
        <views:CheckCollectionView Grid.Row="3" DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" /> 
           ...etc...
    </Grid>
</ScrollViewer>

编辑:DiagramView UserControl包含以下内容:

<UserControl x:Class="Expense.Manager.WPF.Views.DiagramView"
         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:pie="clr-namespace:Expense.Manager.WPF.CustomPie"
         xmlns:local="clr-namespace:Expense.Manager.WPF.Shared"
         mc:Ignorable="d">
<UserControl.Resources>
    <local:BoolToBrushConverter x:Key="BoolToBrushConverter" />
</UserControl.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Income this month: " />
            <TextBlock>
                <TextBlock.Text>
                    <PriorityBinding FallbackValue="Retrieving data...">
                        <Binding Path="EncryptedCurrentMonthIncome" Mode="TwoWay" IsAsync="True" />
                    </PriorityBinding>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
        <pie:PieChart Data="{Binding PieChartIncomeData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
    </StackPanel>

    <StackPanel Grid.Row="0" Grid.Column="1">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Expenses this month: " />
            <TextBlock>
                <TextBlock.Text>
                    <PriorityBinding FallbackValue="Retrieving data...">
                        <Binding Path="CurrentMonthExpense" Mode="TwoWay" IsAsync="True" />
                    </PriorityBinding>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
        <pie:PieChart Data="{Binding PieChartExpenseData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
    </StackPanel>

    <StackPanel Grid.Column="2">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding VacationsLeft}" />
            <TextBlock Text=" days left" />
        </StackPanel>
        <ItemsControl ItemsSource="{Binding VacationsPerYearCollection}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Rectangle Margin="5, 0, 0, 0" Height="25" Width="4" Fill="{Binding Converter={StaticResource BoolToBrushConverter}}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Bank savings:" />
            <TextBlock Text="{Binding BankSavings}" />
        </StackPanel>
    </StackPanel>
</Grid>

IncomeCollectionView:

<UserControl x:Class="Expense.Manager.WPF.Views.IncomeCollectionView"
         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:views="clr-namespace:Expense.Manager.WPF.Views"
         mc:Ignorable="d">
<UserControl.Resources>
    <CollectionViewSource x:Key="groupedCollection" IsLiveGroupingRequested="True" Source="{Binding Collection}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="CurrentCategory" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TextBlock Text="{Binding DisplayName}" Foreground="White" FontWeight="SemiBold" Padding="5" Background="SteelBlue" />
            <ListView Grid.Row="1" ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
                <ListView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Items[0].CurrentCategory}" />
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </ListView.GroupStyle>
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Columns="12" Rows="1" />
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemContainerStyle>
                    <Style>
                        <Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <TextBlock Text="{Binding EncryptedAmount}" />
                            <TextBlock Grid.Row="1" Text="{Binding Date}" />
                            <Button Grid.Row="2" Content="details"
                                Command="{Binding Path=DataContext.ShowDialogCommand,
                                RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
                                CommandParameter="QuickEdit"/>
                            <Button Grid.Row="3" Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />

                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    </Grid>

以及使用它的地方: 为什么在调整窗口大小后,列表视图不会自行调整大小?

    <ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
    </Grid>
</ScrollViewer>

1 个答案:

答案 0 :(得分:0)

我尝试删除StackPanel实施并尝试使用Grid。不,它也不起作用。

除了最后一句话,这几乎是正确的。使用Grid是答案的一半,因为StackPanel没有调整项目大小的功能......您只需要通知ScrollViewer何时滚动。举个例子:

<ScrollViewer>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <Rectangle Fill="Cyan" />
        <Rectangle Grid.Row="1" Fill="Green" />
        <Rectangle Grid.Row="2" Fill="Red" />
        <Rectangle Grid.Row="3" Fill="Blue" />
        <Rectangle Grid.Row="4" Fill="Orange" />
        <Rectangle Grid.Row="5" Fill="Purple" />
        <Rectangle Grid.Row="6" Fill="Yellow" />
    </Grid>
</ScrollViewer>

此XAML将显示ScrollViewer ScrollBarWindow.Height足够小时),但如果删除RowDefinition.Height值(从而为每一行提供整个Grid.Height的一部分ScrollBar 1}}),您会看到之前没有出现Auto的情况。

现在,我们都不想将常量值硬编码到我们的UI中,但您可以使用RowDefinition.Height属性上的Rectangle设置来执行此操作。与这些Height不同,您的控件都会有一些Grid.RowDefinition,因此您的解决方案是将<RowDefinition Height="Auto" /> 设置为:

Grid

这将为您的控件提供Height内所需的空间,因此(希望)他们将比ScrollViewer拥有更多ScrollViewer因此{{1} }}将显示其垂直ScrollBar