除非我设置宽度,否则无法滚动

时间:2013-11-06 14:59:12

标签: c# wpf xaml scroll

我的WPF应用程序将时间轴显示为UserControl,因此使用滚动查看器。

UserControl的宽度取决于某些值,因此可以是0像素宽到N宽。

我遇到的问题是让WPF知道这有多宽。

<UserControl x:Class="TimeLineCanvas.UserControls.TimeLine"
         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:helper="clr-namespace:TimeLineCanvas.Helpers"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=Window}}">
<Grid>

    <Grid.Resources>
        <ResourceDictionary Source="../ResourceDictionary.xaml" />
    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition Height="300" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="450"></ColumnDefinition>
        <ColumnDefinition Width="200"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="0" Grid.Column="0" Margin="10">
        <Grid>
            <!--<Grid HorizontalAlignment="Left" Width="500">-->

            <Grid.RowDefinitions>
                <RowDefinition Height="40" />
                <RowDefinition Height="110" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Canvas x:Name="MyCanvasMarkers" Grid.Row="0"  VerticalAlignment="Top" Grid.Column="0" /> <!-- this will always be the widest of the canvas's-->

            <Canvas x:Name="MyCanvasShowEvents" Grid.Row="1" Grid.Column="0" />

            <Canvas x:Name="MyCanvasFailEvents" Grid.Row="1" Grid.Column="0" />
        </Grid>
    </ScrollViewer>

    <!-- I doubt anything below this is useful for this post but I keep it in case I'm wrong-->

    <Grid x:Name="ConfigurationGrid" Grid.Column="1" Grid.Row="0" >

        <StackPanel>
            <Expander IsExpanded="True">
                <Expander.Header>
                    <TextBlock Text="Zoom" />
                </Expander.Header>
                <Expander.Content>
                    <Border Style="{StaticResource LightBorder}">
                        <StackPanel>

                            <TextBlock Text="Select Zoom Out Level" />
                            <ComboBox ItemsSource="{Binding ScaleFactorOptions}" 
              SelectedItem="{Binding SelectedScaleFactor, UpdateSourceTrigger=PropertyChanged}"                   
              HorizontalAlignment="Left" 
              SelectionChanged="ZoomLevel_SelectionChanged"
              >
                                <ComboBox.Resources>
                                    <helper:ZoomConverter x:Key="ZoomConverter" />
                                </ComboBox.Resources>
                                <ComboBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Converter={StaticResource ZoomConverter}}" />
                                    </DataTemplate>
                                </ComboBox.ItemTemplate>
                            </ComboBox>
                        </StackPanel>
                    </Border>
                </Expander.Content>
            </Expander>

            <Expander IsExpanded="True" >
                <Expander.Header>
                    <TextBlock Text="Time Period" />
                </Expander.Header>
                <Expander.Content>
                    <Border Style="{StaticResource LightBorder}">
                        <StackPanel>
                            <TextBlock Text="Change Time Period" />
                            <ComboBox ItemsSource="{Binding PeriodOptions}" 
              SelectedItem="{Binding SelectedPeriod, UpdateSourceTrigger=PropertyChanged}"                   
              HorizontalAlignment="Left" 
              SelectionChanged="TimePeriod_SelectionChanged"
              >
                            </ComboBox>
                        </StackPanel>
                    </Border>
                </Expander.Content>
            </Expander>

            <Expander IsExpanded="True">
                <Expander.Header>
                    <TextBlock Text="Properties" />
                </Expander.Header>
                <Expander.Content>
                    <Border Style="{StaticResource LightBorder}">
                        <StackPanel>
                            <TextBlock x:Name="txtProperty"/>
                        </StackPanel>
                    </Border>
                </Expander.Content>
            </Expander>
        </StackPanel>
    </Grid>
</Grid>

正如您在上面的代码中所看到的,我已经注释掉了一行,我将宽度设置为500.当我这样做时,滚动条出现,我可以滚动查找该值,该值可能与也可能不一致画布的宽度。

我还尝试添加ColumnDefintion = Auto只是为了看看这是否会有所帮助,但事实并非如此。

我是否必须弄清楚Canvas在后面的代码中的宽度,然后手动设置宽度,或者XAML可以使用Stretch属性中的HoriztonalAlignment自动执行此操作(或者类似)?

3 个答案:

答案 0 :(得分:0)

就像现在一样,你有所有控件自动调整大小以适应他们的内容,这种方式违背了ScrollViewer的目的。相反,摆脱Grid并将HorizontalAlignment上的ScrollViewer设置为Stretch(或手动为其分配大小)。

答案 1 :(得分:0)

您可以将网格的width属性绑定到画布的width属性

例如在网格中:

Width="{Binding ElementName=youcanvas, Path=Width}"

答案 2 :(得分:0)

试试这个

<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
    <Grid>

        <Grid.Resources>
            <ResourceDictionary Source="../ResourceDictionary.xaml" />
        </Grid.Resources>

        <Grid.RowDefinitions>
            <RowDefinition Height="300" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="450"></ColumnDefinition>
            <ColumnDefinition Width="200"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="0" Grid.Column="0" Margin="10">
            <Grid>
                <!--<Grid HorizontalAlignment="Left" Width="500">-->

                <Grid.RowDefinitions>
                    <RowDefinition Height="40" />
                    <RowDefinition Height="110" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Canvas x:Name="MyCanvasMarkers" Grid.Row="0" VerticalAlignment="Top" Grid.Column="0" />
                <!-- this will always be the widest of the canvas's-->

                <Canvas x:Name="MyCanvasShowEvents" Grid.Row="1" Grid.Column="0" />

                <Canvas x:Name="MyCanvasFailEvents" Grid.Row="1" Grid.Column="0" />
            </Grid>
        </ScrollViewer>

        <!-- I doubt anything below this is useful for this post but I keep it in case I'm wrong-->

        <Grid x:Name="ConfigurationGrid" Grid.Column="1" Grid.Row="0">

            <StackPanel>
                <Expander IsExpanded="True">
                    <Expander.Header>
                        <TextBlock Text="Zoom" />
                    </Expander.Header>
                    <Expander.Content>
                        <Border Style="{StaticResource LightBorder}">
                            <StackPanel>

                                <TextBlock Text="Select Zoom Out Level" />
                                <ComboBox ItemsSource="{Binding ScaleFactorOptions}"
                                          SelectedItem="{Binding SelectedScaleFactor, UpdateSourceTrigger=PropertyChanged}"
                                          HorizontalAlignment="Left"
                                          SelectionChanged="ZoomLevel_SelectionChanged">
                                    <ComboBox.Resources>
                                        <helper:ZoomConverter x:Key="ZoomConverter" />
                                    </ComboBox.Resources>
                                    <ComboBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding Converter={StaticResource ZoomConverter}}" />
                                        </DataTemplate>
                                    </ComboBox.ItemTemplate>
                                </ComboBox>
                            </StackPanel>
                        </Border>
                    </Expander.Content>
                </Expander>

                <Expander IsExpanded="True">
                    <Expander.Header>
                        <TextBlock Text="Time Period" />
                    </Expander.Header>
                    <Expander.Content>
                        <Border Style="{StaticResource LightBorder}">
                            <StackPanel>
                                <TextBlock Text="Change Time Period" />
                                <ComboBox ItemsSource="{Binding PeriodOptions}"
                                          SelectedItem="{Binding SelectedPeriod, UpdateSourceTrigger=PropertyChanged}"
                                          HorizontalAlignment="Left"
                                          SelectionChanged="TimePeriod_SelectionChanged">
                                </ComboBox>
                            </StackPanel>
                        </Border>
                    </Expander.Content>
                </Expander>

                <Expander IsExpanded="True">
                    <Expander.Header>
                        <TextBlock Text="Properties" />
                    </Expander.Header>
                    <Expander.Content>
                        <Border Style="{StaticResource LightBorder}">
                            <StackPanel>
                                <TextBlock x:Name="txtProperty" />
                            </StackPanel>
                        </Border>
                    </Expander.Content>
                </Expander>
            </StackPanel>
        </Grid>
    </Grid>
</ScrollViewer>

就像Adam说的那样,你的控件是自动调整大小,所以它不知道ScrollViewer应滚动到的“MaxWidth”是什么,这就是它被禁用的原因。

更新1:由于外部有更多控件,因此您需要在外部使用ScrollViewer,以便定义整个滚动区域。 Grid是指示内部滚动查看器的滚动区域及其自动大小,因此它不知道。将ScrollViewer包装在外部将知道其整体滚动区域,以便内部的ScrollViewer也可以按预期运行。