2

很多时候有人问“如何将滚动查看器自动滚动到底部?”。我是一个幸运的人。绑定上下文后,我的 ScrollViewer 毫不费力地向下滚动。我讨厌它!

这是标记:

<UserControl x:Class="TradeSharp.Client.Subscription.Control.PerformerStatistics"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay" 
         xmlns:Charts="clr-namespace:Microsoft.Research.DynamicDataDisplay.Charts;assembly=DynamicDataDisplay" 
         xmlns:local="clr-namespace:TradeSharp.Client.Subscription.Control" xmlns:ModelView="clr-namespace:TradeSharp.Client.Subscription.ModelView"
         xmlns:c="clr-namespace:TradeSharp.Client.Subscription.Control.PieChart" mc:Ignorable="d"
         HorizontalAlignment="Stretch"             
         Height="460"
         d:DesignHeight="300" 
         d:DesignWidth="600" Loaded="UserControlLoaded">
<UserControl.Resources>
    <ResourceDictionary>            
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Theme/Theme.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <x:ArrayExtension Type="{x:Type Brush}" x:Key="brushesPie">
            <SolidColorBrush Color="#CACACA"/>
            <SolidColorBrush Color="#EAE495"/>
            <SolidColorBrush Color="#776611"/>
            <SolidColorBrush Color="#888888"/>
            <SolidColorBrush Color="#FFFFFF"/>
            <SolidColorBrush Color="#880000"/>
            <SolidColorBrush Color="#EA8876"/>
            <SolidColorBrush Color="#995599"/>
            <SolidColorBrush Color="#B0B0B0"/>
        </x:ArrayExtension>
    </ResourceDictionary>
</UserControl.Resources>

<!-- 3 rows: stats, charts, tables -->
<ScrollViewer Name="ContentScrollViewer" VerticalScrollBarVisibility="Disabled">
    <Grid HorizontalAlignment="Stretch" Canvas.Left="0" Canvas.Top="0">
        <Grid.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Color="#FF4A4A4A" Offset="0" ></GradientStop>
                <GradientStop Color="#FF303030" Offset="0.02" ></GradientStop>
            </LinearGradientBrush>
        </Grid.Background>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100*" />
        </Grid.ColumnDefinitions>            

        <Grid Grid.Row="0" Grid.Column="0" local:GridMarginSetter.Margin="8">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0" Content="{Binding Path=SignalTitle}" FontSize="13" />
            <Button Grid.Row="0" Grid.Column="1" Content="{Binding Path=SubscriptionButtonTitle}" 
                FontSize="11" Padding="6,4" Click="ButtonClick" />
        </Grid>

        <!-- stats -->
        <Grid Grid.Row="1" Grid.Column="0" local:GridMarginSetter.Margin="8">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Content="Доходность, %:" />
            <Label Grid.Row="0" Grid.Column="1" Content="{Binding Path=Efficiency.TWR}" ContentStringFormat="{}{0:F2}" />

            <Label Grid.Row="0" Grid.Column="2" Content="Кол-во подписчиков:" />
            <Label Grid.Row="0" Grid.Column="3" Content="{Binding Path=Performer.SubscriberCount}" />

            <Label Grid.Row="0" Grid.Column="4" Content="К. Шарпа:" />
            <Label Grid.Row="0" Grid.Column="5" Content="{Binding Path=Efficiency.Sharp}" ContentStringFormat="{}{0:F3}" />

            <Label Grid.Row="1" Grid.Column="0" Content="Макс. проседание, %:" />
            <Label Grid.Row="1" Grid.Column="1" Content="{Binding Path=Efficiency.MaxDrawdown}" ContentStringFormat="{}{0:F2}" />

            <Label Grid.Row="1" Grid.Column="2" Content="Сделок всего:" />
            <Label Grid.Row="1" Grid.Column="3" Content="{Binding Path=Efficiency.DealsCount}" />

            <Label Grid.Row="1" Grid.Column="4" Content="Сделок открытых:" />
            <Label Grid.Row="1" Grid.Column="5" Content="{Binding Path=Efficiency.DealsStillOpened}" />

            <Label Grid.Row="2" Grid.Column="0" Content="С.геом. доходность (месяц), %:" />
            <Label Grid.Row="2" Grid.Column="1" Content="{Binding Path=Efficiency.ProfitGeomMonth}" ContentStringFormat="{}{0:F3}" />

            <Label Grid.Row="2" Grid.Column="2" Content="С.геом. доходность (год), %:" />
            <Label Grid.Row="2" Grid.Column="3" Content="{Binding Path=Efficiency.ProfitGeomYear}" ContentStringFormat="{}{0:F3}" />

            <Label Grid.Row="2" Grid.Column="4" Content="Ср. прибыль / ср. убыток:" />
            <Label Grid.Row="2" Grid.Column="5" Content="{Binding Path=Efficiency.GreedyRatio}" ContentStringFormat="{}{0:F3}" />

            <Label Grid.Row="3" Grid.Column="0" Content="Макс. плечо:" />
            <Label Grid.Row="3" Grid.Column="1" Content="{Binding Path=Efficiency.MaxLeverage}" ContentStringFormat="{}{0:F2}" />

            <Label Grid.Row="3" Grid.Column="2" Content="Сред. плечо:" />
            <Label Grid.Row="3" Grid.Column="3" Content="{Binding Path=Efficiency.AvgLeverage}" ContentStringFormat="{}{0:F2}" />
        </Grid>

        <!-- Profit chart -->
        <d3:ChartPlotter Name="plotter" 
                        Grid.Row="2" Grid.Column="0"
                        Margin="5, 5" LegendVisible="False">

            <d3:ChartPlotter.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Color="#FF4A4A4A" Offset="0" ></GradientStop>
                    <GradientStop Color="#FF303030" Offset="0.08" ></GradientStop>
                </LinearGradientBrush>
            </d3:ChartPlotter.Background>

            <d3:AxisGrid Foreground="Silver"></d3:AxisGrid>

            <d3:VerticalAxisTitle>Доходность, USD</d3:VerticalAxisTitle>

            <d3:LineGraph Name="chartProfit"
                        DataSource="{Binding Path=ListEquity}" 
                        Stroke="White" 
                        StrokeThickness="2" 
                        Height="260" 
                        Width="Auto"
                        HorizontalAlignment="Stretch">
            </d3:LineGraph>

            <d3:Plotter.Foreground>
                <SolidColorBrush Color="Silver"></SolidColorBrush>
            </d3:Plotter.Foreground>

            <d3:ChartPlotter.HorizontalAxis>
                <Charts:HorizontalDateTimeAxis Name="dateAxis" Foreground="Silver">
                </Charts:HorizontalDateTimeAxis>
            </d3:ChartPlotter.HorizontalAxis>

        </d3:ChartPlotter>

        <!-- Доходность, на 1000 -->
        <d3:ChartPlotter Name="plotter1000" 
                        Grid.Row="3" Grid.Column="0"
                        Margin="5, 8" LegendVisible="False">

            <d3:ChartPlotter.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Color="#FF4A4A4A" Offset="0" ></GradientStop>
                    <GradientStop Color="#FF303030" Offset="0.08" ></GradientStop>
                </LinearGradientBrush>
            </d3:ChartPlotter.Background>

            <d3:AxisGrid Foreground="Silver"></d3:AxisGrid>

            <d3:VerticalAxisTitle>Доходность на $1000</d3:VerticalAxisTitle>

            <d3:LineGraph Name="chartProfit1000"
                        DataSource="{Binding Path=ListProfit1000}" 
                        Stroke="White" 
                        StrokeThickness="2" 
                        Height="260" 
                        Width="Auto"
                        HorizontalAlignment="Stretch">
            </d3:LineGraph>

            <d3:Plotter.Foreground>
                <SolidColorBrush Color="Silver"></SolidColorBrush>
            </d3:Plotter.Foreground>

            <d3:ChartPlotter.HorizontalAxis>
                <Charts:HorizontalDateTimeAxis Name="dateAxis1000" Foreground="Silver">
                </Charts:HorizontalDateTimeAxis>
            </d3:ChartPlotter.HorizontalAxis>

        </d3:ChartPlotter>

        <!-- deals' table -->
        <Expander Name="dealExpander" Grid.Row="4" Grid.Column="0"
                  Header="Открытые сделки"
                  Margin="5" Padding="6"
                  Expanded="DealExpanderExpanded" IsExpanded="False">                
            <DataGrid Name="dealTableOpened"
                      CanUserAddRows="False" 
                      IsReadOnly="True"
                      AutoGenerateColumns="False"
                      HeadersVisibility="Column">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="№" Binding="{Binding Path=ID}" Width="14*" />
                    <DataGridTextColumn Header="Инстр." Binding="{Binding Path=Symbol}" Width="15*" />
                    <DataGridTextColumn Header="Тип" Binding="{Binding Path=Side, Converter={ModelView:DealSideConverter}}" Width="14*" />
                    <DataGridTextColumn Header="Объем" Binding="{Binding Path=Volume, Converter={ModelView:DealVolumeConverter}}" Width="19*" />
                    <DataGridTextColumn Header="Вход" Binding="{Binding Path=PriceEnter, Converter={ModelView:DealPriceConverter}}" Width="22*" />
                    <DataGridTextColumn Header="Время" Binding="{Binding Path=TimeEnter, StringFormat={}{0:dd.MM.yyyy HH:mm}}" Width="26*" />
                </DataGrid.Columns>
            </DataGrid>
        </Expander>

        <!-- some pie chart -->
        <Expander Name="dealByTickerExpander" Grid.Row="5" Grid.Column="0"
                  Header="Сделок по инструменту"
                  Margin="5" Padding="6"
                  Expanded="DealByTickerExpanderExpanded"
                  IsExpanded="False">
            <c:PieChartLayout                     
                x:Name="chartCountByTicker"
                DataContext="{x:Null}"
                PlottedProperty="DealCount" 
                LegendTitle="Инструмент"
                Margin="10">                    
                <c:PieChartLayout.ColorSelector>
                    <c:IndexedColourSelector Brushes="{StaticResource brushesPie}"/>
                </c:PieChartLayout.ColorSelector>
            </c:PieChartLayout>
        </Expander>
    </Grid>
</ScrollViewer>
</UserControl>

后面的代码没有什么特别之处。只是通过将ContentScrollViewer.VerticalScrollBarVisibility设置为禁用然后再次自动来停止滚动的尝试失败。

public void BindData(PerformerStat performer, bool isSubscribed)
    {
        viewModel = new PerformerStatiscticsViewModel(performer, dateAxis.ConvertToDouble,
                                                      dateAxis1000.ConvertToDouble,
                                                      isSubscribed);

        worker.DoWork += (o, e) =>
                             {
                                 try
                                 {
                                     viewModel.GetPerformerEfficiency();
                                 }
                                 catch (Exception ex)
                                 {
                                     viewModel = null;
                                 }                                     
                             };
        worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
        worker.RunWorkerAsync();
    }

    private void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (viewModel == null) return;
        DataContext = viewModel;
        ContentScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
    }
4

0 回答 0