5

スクロールバーを使用せずに、タッチ スクリーン アプリケーション用のカスタム スクロール ビューアー コントロールを作成したいと考えています。コンテンツをスクロールできることをユーザーに知らせるために、不透明マスクを使用して線形グラデーションでスクロールビューアーの下部と上部をフェードしています。スクロールビューアに加えてテキストブロックに適用される不透明マスクの問題を除いて、これはすべて正常に機能します!

つまり、フェード効果をスクロールビューアーの上部 1% と下部 1% に適用すると、スクロールビューアーの中央が表示されるようになります。ただし、問題は、テキストブロックに OpacityMask="{x:Null}" を設定しても、スクロールビューア内のコントロールでもこの​​効果が発生していることです。

スクロールビューアの外側にも不透明マスクを適用しようとしましたが、同じ問題が発生します。Opacitymask プロパティは子にも適用されますか? このフェード効果を行うためのより良い方法はありますか?

私が使用しているコードは次のとおりです。

<Grid Width="200" Height="130">
    <ScrollViewer BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2"
                           HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden" >
        <ScrollViewer.OpacityMask>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0" />
                <GradientStop Color="Black" Offset="0.1" />
                <GradientStop Color="Black" Offset="0.9" />
                <GradientStop Color="Transparent" Offset="1" />
            </LinearGradientBrush>
        </ScrollViewer.OpacityMask>
        <TextBlock Margin="0,10" Style="{StaticResource textSmall}" TextWrapping="Wrap">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
        </TextBlock>
    </ScrollViewer>
</Grid>
4

5 に答える 5

6

これは古い質問であることは知っていますが、似たようなことをしようとしていたので、この質問に出くわしました。だから私は次の人のために私の解決策を投稿すると思った. 私のソリューションに関するフィードバックは大歓迎です。

私たちのアプリケーションでは、ほとんどの ScrollViewer コントロールが非スクロール テクスチャの上に置かれているため、スクロール可能なコンテンツが ScrollViewer の端でその背景にフェードインするようにしましたが、その方向にさらにコンテンツがある場合のみでした。さらに、ユーザーがあらゆる方向にパンできる 2 軸のスクロール可能な領域が少なくとも 1 つあります。そのシナリオでも機能する必要がありました。私たちのアプリケーションには実際にはスクロールバーもありませんが、ここで紹介するソリューションから除外しました (ソリューションには影響しません)。

このソリューションの特徴:

  1. ScrollViewer のその側に現在表示されていないコンテンツがある場合、ScrollViewer 内のコンテンツの端をフェードします。

  2. スクロールしてコンテンツの端に近づくにつれて、フェード効果の強度が減少します。

  3. フェード エッジの外観をある程度制御できます。具体的には、以下を制御できます。

    1. フェード エッジの厚さ
    2. コンテンツの最も外側の不透明度 (またはフェードの「強さ」)
    3. 端近くをスクロールしたときにフェード効果が消える速さ

基本的な考え方は、ScrollViewer のテンプレートでスクロール可能なコンテンツに対して不透明マスクを制御することです。不透明度マスクには、透明な外側の境界線と、エッジでグラデーション効果を得るために BlurEffect が適用された内側の不透明な境界線が含まれています。次に、スクロールしながら内側の境界線のマージンを操作し、特定のエッジに沿ってフェードがどの程度「深く」表示されるかを制御します。

このソリューションは ScrollViewer をサブクラス化し、ScrollViewer のテンプレートに変更を指定する必要があります。ScrollContentPresenter は、「PART_ScrollContentPresenterContainer」という名前の Border 内にラップする必要があります。

FadingScrollViewer クラス

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;

namespace ScrollViewerTest
{
  public class FadingScrollViewer : ScrollViewer
  {
    private const string PART_SCROLL_PRESENTER_CONTAINER_NAME = "PART_ScrollContentPresenterContainer";

    public double FadedEdgeThickness { get; set; }
    public double FadedEdgeFalloffSpeed { get; set; }
    public double FadedEdgeOpacity { get; set; }

    private BlurEffect InnerFadedBorderEffect { get; set; }
    private Border InnerFadedBorder { get; set; }
    private Border OuterFadedBorder { get; set; }



    public FadingScrollViewer()
    {
      this.FadedEdgeThickness = 20;
      this.FadedEdgeFalloffSpeed = 4.0;
      this.FadedEdgeOpacity = 0.0;

      this.ScrollChanged += FadingScrollViewer_ScrollChanged;
      this.SizeChanged += FadingScrollViewer_SizeChanged;
    }



    private void FadingScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
      if (this.InnerFadedBorder == null)
        return;

      var topOffset = CalculateNewMarginBasedOnOffsetFromEdge(this.VerticalOffset); ;
      var bottomOffset = CalculateNewMarginBasedOnOffsetFromEdge(this.ScrollableHeight - this.VerticalOffset);
      var leftOffset = CalculateNewMarginBasedOnOffsetFromEdge(this.HorizontalOffset);
      var rightOffset = CalculateNewMarginBasedOnOffsetFromEdge(this.ScrollableWidth - this.HorizontalOffset);

      this.InnerFadedBorder.Margin = new Thickness(leftOffset, topOffset, rightOffset, bottomOffset);
    }



    private double CalculateNewMarginBasedOnOffsetFromEdge(double edgeOffset)
    {
      var innerFadedBorderBaseMarginThickness = this.FadedEdgeThickness / 2.0;
      var calculatedOffset = (innerFadedBorderBaseMarginThickness) - (1.5 * (this.FadedEdgeThickness - (edgeOffset / this.FadedEdgeFalloffSpeed)));

      return Math.Min(innerFadedBorderBaseMarginThickness, calculatedOffset);
    }



    private void FadingScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
      if (this.OuterFadedBorder == null || this.InnerFadedBorder == null || this.InnerFadedBorderEffect == null)
        return;

      this.OuterFadedBorder.Width = e.NewSize.Width;
      this.OuterFadedBorder.Height = e.NewSize.Height;

      double innerFadedBorderBaseMarginThickness = this.FadedEdgeThickness / 2.0;
      this.InnerFadedBorder.Margin = new Thickness(innerFadedBorderBaseMarginThickness);
      this.InnerFadedBorderEffect.Radius = this.FadedEdgeThickness;
    }



    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      BuildInnerFadedBorderEffectForOpacityMask();
      BuildInnerFadedBorderForOpacityMask();
      BuildOuterFadedBorderForOpacityMask();
      SetOpacityMaskOfScrollContainer();
    }



    private void BuildInnerFadedBorderEffectForOpacityMask()
    {
      this.InnerFadedBorderEffect = new BlurEffect()
        {
          RenderingBias = RenderingBias.Performance,
        };
    }



    private void BuildInnerFadedBorderForOpacityMask()
    {
      this.InnerFadedBorder = new Border()
        {
          Background = Brushes.Black,
          HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
          VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
          Effect = this.InnerFadedBorderEffect,
        };
    }



    private void BuildOuterFadedBorderForOpacityMask()
    {
      byte fadedEdgeByteOpacity = (byte)(this.FadedEdgeOpacity * 255);

      this.OuterFadedBorder = new Border()
        {
          Background = new SolidColorBrush(Color.FromArgb(fadedEdgeByteOpacity, 0, 0, 0)),
          ClipToBounds = true,
          Child = this.InnerFadedBorder,
        };
    }



    private void SetOpacityMaskOfScrollContainer()
    {
      var opacityMaskBrush = new VisualBrush()
        {
          Visual = this.OuterFadedBorder
        };

      var scrollContentPresentationContainer = this.Template.FindName(PART_SCROLL_PRESENTER_CONTAINER_NAME, this) as UIElement;

      if (scrollContentPresentationContainer == null)
        return;

      scrollContentPresentationContainer.OpacityMask = opacityMaskBrush;
    }
  }
}

コントロールを使用するための XAML を次に示します。必要な既定の ScrollViewer テンプレートへの最小限の変更が必要です (ScrollContentPresenter の周囲の境界線です)。

<local:FadingScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" Margin="10" FadedEdgeThickness="20" FadedEdgeOpacity="0" FadedEdgeFalloffSpeed="4">
  <local:FadingScrollViewer.Template>
    <ControlTemplate TargetType="{x:Type ScrollViewer}">
      <Grid x:Name="Grid" Background="{TemplateBinding Background}">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="*"/>
          <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Border x:Name="PART_ScrollContentPresenterContainer">
          <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
        </Border>

        <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
        <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
      </Grid>
    </ControlTemplate>
  </local:FadingScrollViewer.Template>


  <!-- Your content here -->

</local:FadingScrollViewer>

FadedScrollViewer の次の追加プロパティに注意してください: FadedEdgeThickness、FadedEdgeOpacity、および FadedEdgeFalloffSpeed

  • FadedEdgeThickness: フェードの厚さ (ピクセル単位)
  • FadedEdgeOpacity: フェードの最も外側のエッジの不透明度。0 = エッジで完全に透明、1 = エッジでまったくフェードしない
  • FadedEdgeFalloffSpeed: フェード エッジに近づくと、フェード エッジが消える速さを制御します。値が大きいほど、フェードアウトが遅くなります。
于 2012-10-25T18:47:43.930 に答える
4

おじいちゃんのコードを、カスタム コントロールを使用せずに動作するように変更しました。このように、添付のプロパティを追加するだけで、すべての ScrollViewer をフェーディング スクロールビューアに「アップグレード」できます。とにかくスクロールビューアのスタイルを指定する必要があります。PART_ScrollContentPresenterContainer という名前を定義する必要があります。おじいちゃんスタイルはそのままお使いいただけます。

クラスのコード (ScrollViewerExtensions と呼ばれる) は次のとおりです。

/// <summary>
/// Attached property that makes the scrollbar fade on it's edges
/// 
/// derived class at from http://stackoverflow.com/questions/1901709/scrollviewer-edge-blur-effect-opacitymask-not-working-properly
/// </summary>
public class ScrollViewerExtensions : DependencyObject
{
    /// <summary>
    /// MAIN property: this activates the whole fading effect
    /// </summary>
    public static readonly DependencyProperty FadedEdgeThicknessProperty =
        DependencyProperty.RegisterAttached("FadedEdgeThickness", typeof(double), typeof(ScrollViewerExtensions), new PropertyMetadata(20.0d, OnFadedEdgeThicknessChanged));

    public static void SetFadedEdgeThickness(ScrollViewer s, double value)
    {
        s.SetValue(FadedEdgeThicknessProperty, value);
    }

    public static double GetFadedEdgeThickness(ScrollViewer s, double value)
    {
        return (double)s.GetValue(FadedEdgeThicknessProperty);
    }

    /// <summary>
    /// optional property. changes how fast the fade appears/diappears when scrolling near an edge
    /// </summary>
    public static readonly DependencyProperty FadedEdgeFalloffSpeedProperty =
        DependencyProperty.RegisterAttached("FadedEdgeFalloffSpeed", typeof(double), typeof(ScrollViewerExtensions), new PropertyMetadata(4.0d, OnFadedEdgeFalloffSpeedChanged));

    public static void SetFadedEdgeFalloffSpeed(ScrollViewer s, double value)
    {
        s.SetValue(FadedEdgeFalloffSpeedProperty, value);
    }

    public static double GetFadedEdgeFalloffSpeed(ScrollViewer s, double value)
    {
        return (double)s.GetValue(FadedEdgeFalloffSpeedProperty);
    }

    /// <summary>
    /// optional property. changes how opaque the outermost edge should be
    /// </summary>
    public static readonly DependencyProperty FadedEdgeOpacityProperty =
        DependencyProperty.RegisterAttached("FadedEdgeOpacity", typeof(double), typeof(ScrollViewerExtensions), new PropertyMetadata(0.0d, OnFadedEdgeOpacityChanged));

    public static void SetFadedEdgeOpacity(ScrollViewer s, double value)
    {
        s.SetValue(FadedEdgeOpacityProperty, value);
    }

    public static double GetFadedEdgeOpacity(ScrollViewer s, double value)
    {
        return (double)s.GetValue(FadedEdgeOpacityProperty);
    }




    private const string PART_SCROLL_PRESENTER_CONTAINER_NAME = "PART_ScrollContentPresenterContainer";

    private static Dictionary<ScrollViewer, FadeSettings> Settings = new Dictionary<ScrollViewer, FadeSettings>();



    /// <summary>
    /// this is kindof the constructor for the properties. If you don't specify this, nothing will fade!
    /// </summary>
    /// <param name="d"></param>
    /// <param name="e"></param>
    public static void OnFadedEdgeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var scrollViewer = d as ScrollViewer;

        if (scrollViewer == null)
            return;

        double edgeThickness = (double)e.NewValue;

        scrollViewer.ScrollChanged += FadingScrollViewer_ScrollChanged;
        scrollViewer.SizeChanged += FadingScrollViewer_SizeChanged;

        if (!Settings.ContainsKey(scrollViewer))
            Settings.Add(scrollViewer, new FadeSettings());

        Settings[scrollViewer].FadedEdgeThickness = edgeThickness;
    }


    public static void OnFadedEdgeFalloffSpeedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var scrollViewer = d as ScrollViewer;

        if (scrollViewer == null)
            return;

        double edgeFalloffSpeed = (double)e.NewValue;

        if (!Settings.ContainsKey(scrollViewer))
            Settings.Add(scrollViewer, new FadeSettings());

        Settings[scrollViewer].FadedEdgeFalloffSpeed = edgeFalloffSpeed;
    }


    public static void OnFadedEdgeOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var scrollViewer = d as ScrollViewer;

        if (scrollViewer == null)
            return;

        double edgeOpacity = (double)e.NewValue;

        if (!Settings.ContainsKey(scrollViewer))
            Settings.Add(scrollViewer, new FadeSettings());

        Settings[scrollViewer].FadedEdgeOpacity = edgeOpacity;
    }


    private static void FadingScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ScrollViewer scrollViewer = sender as ScrollViewer;
        FadeSettings settings = Settings[scrollViewer];

        if (settings.InnerFadedBorder == null)
            return;

        var topOffset = CalculateNewMarginBasedOnOffsetFromEdge(scrollViewer, scrollViewer.VerticalOffset); ;
        var bottomOffset = CalculateNewMarginBasedOnOffsetFromEdge(scrollViewer, scrollViewer.ScrollableHeight - scrollViewer.VerticalOffset);
        var leftOffset = CalculateNewMarginBasedOnOffsetFromEdge(scrollViewer, scrollViewer.HorizontalOffset);
        var rightOffset = CalculateNewMarginBasedOnOffsetFromEdge(scrollViewer, scrollViewer.ScrollableWidth - scrollViewer.HorizontalOffset);

        settings.InnerFadedBorder.Margin = new Thickness(leftOffset, topOffset, rightOffset, bottomOffset);
    }

    private static void FadingScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        ScrollViewer scrollViewer = sender as ScrollViewer;
        FadeSettings settings = Settings[scrollViewer];

        if (!settings.Initialized) // abuse the SizeChanged event to call the OnApplyTemplate method. We can't override it, so we need something, that fires after it would normally be called. see http://msdn.microsoft.com/en-us/library/dd351483%28v=vs.95%29.aspx
        {
            OnApplyTemplate(scrollViewer);
            settings.Initialized = true;
        }

        if (settings.OuterFadedBorder == null || settings.InnerFadedBorder == null || settings.InnerFadedBorderEffect == null)
            return;

        settings.OuterFadedBorder.Width = e.NewSize.Width;
        settings.OuterFadedBorder.Height = e.NewSize.Height;

        double innerFadedBorderBaseMarginThickness = settings.FadedEdgeThickness / 2.0;
        settings.InnerFadedBorder.Margin = new Thickness(innerFadedBorderBaseMarginThickness);
        settings.InnerFadedBorderEffect.Radius = settings.FadedEdgeThickness;
    }

    private static double CalculateNewMarginBasedOnOffsetFromEdge(ScrollViewer scrollViewer, double edgeOffset)
    {
        FadeSettings settings = Settings[scrollViewer];

        var innerFadedBorderBaseMarginThickness = settings.FadedEdgeThickness / 2.0;
        //var calculatedOffset = (innerFadedBorderBaseMarginThickness) - (1.0 * (this.FadedEdgeThickness - (edgeOffset / this.FadedEdgeFalloffSpeed)));

        double calculatedOffset;
        if (edgeOffset == 0)
            calculatedOffset = -innerFadedBorderBaseMarginThickness;
        else
            calculatedOffset = (edgeOffset * settings.FadedEdgeFalloffSpeed) - innerFadedBorderBaseMarginThickness;

        return Math.Min(innerFadedBorderBaseMarginThickness, calculatedOffset);
    }

    public static void OnApplyTemplate(ScrollViewer scrollViewer)
    {
        BuildInnerFadedBorderEffectForOpacityMask(scrollViewer);
        BuildInnerFadedBorderForOpacityMask(scrollViewer);
        BuildOuterFadedBorderForOpacityMask(scrollViewer);
        SetOpacityMaskOfScrollContainer(scrollViewer);
    }

    private static void BuildInnerFadedBorderEffectForOpacityMask(ScrollViewer scrollViewer)
    {
        FadeSettings settings = Settings[scrollViewer];

        settings.InnerFadedBorderEffect = new BlurEffect()
        {
            RenderingBias = RenderingBias.Performance,
        };
    }

    private static void BuildInnerFadedBorderForOpacityMask(ScrollViewer scrollViewer)
    {
        FadeSettings settings = Settings[scrollViewer];

        settings.InnerFadedBorder = new Border()
        {
            Background = Brushes.Black,
            HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
            VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
            Effect = settings.InnerFadedBorderEffect,
        };
    }

    private static void BuildOuterFadedBorderForOpacityMask(ScrollViewer scrollViewer)
    {
        FadeSettings settings = Settings[scrollViewer];

        byte fadedEdgeByteOpacity = (byte)(settings.FadedEdgeOpacity * 255);

        settings.OuterFadedBorder = new Border()
        {
            Background = new SolidColorBrush(Color.FromArgb(fadedEdgeByteOpacity, 0, 0, 0)),
            ClipToBounds = true,
            Child = settings.InnerFadedBorder,
        };
    }

    private static void SetOpacityMaskOfScrollContainer(ScrollViewer scrollViewer)
    {
        FadeSettings settings = Settings[scrollViewer];

        var opacityMaskBrush = new VisualBrush()
        {
            Visual = settings.OuterFadedBorder
        };

        var scrollContentPresentationContainer = scrollViewer.Template.FindName(PART_SCROLL_PRESENTER_CONTAINER_NAME, scrollViewer) as UIElement;

        if (scrollContentPresentationContainer == null)
            return;

        scrollContentPresentationContainer.OpacityMask = opacityMaskBrush;

        // test
        /*var container = scrollContentPresentationContainer as Border;
        var scroller = container.Child as UIElement;
        container.Child = null;

        Grid g = new Grid();
        container.Child = g;

        g.Children.Add(scroller);
        this.OuterFadedBorder.IsHitTestVisible = false;
        g.Children.Add(this.OuterFadedBorder);*/
    }


    protected class FadeSettings
    {
        public BlurEffect InnerFadedBorderEffect { get; set; }
        public Border InnerFadedBorder { get; set; }
        public Border OuterFadedBorder { get; set; }

        public double FadedEdgeThickness { get; set; }
        public double FadedEdgeFalloffSpeed { get; set; }
        public double FadedEdgeOpacity { get; set; }

        public bool Initialized { get; set; }

        public FadeSettings()
        {
            FadedEdgeThickness = 20.0d;
            FadedEdgeFalloffSpeed = 4.0d;
            FadedEdgeOpacity = 0.0d;
        }
    }
}

コードで添付プロパティを設定できます。

scroller.SetValue(ScrollViewerExtensions.FadedEdgeThicknessProperty, 70.0d);

または、XAML で直接定義します。

<ScrollViewer Name="scrollViewer" controls:ScrollViewerExtensions.FadedEdgeThickness="40">
    some content
</ScrollViewer>

皆さんがそれで何かできることを願っています!

于 2013-06-07T12:57:16.837 に答える
2

同じ Grid 内の ScrollViewer の上に透明なグラデーションを持つコントロールを追加し、その 'IsHitTestVisible' を false に設定して、この効果を実現できます。ScrollViewer の上に Canvas コントロールを使用した例の修正版を次に示します。

<Grid Width="200" Height="130">
            <ScrollViewer BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2"
                           HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden"  Background="LightBlue">
                <TextBlock Margin="10,30,10,30" TextWrapping="Wrap" OpacityMask="Black" VerticalAlignment="Center">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
                </TextBlock>
            </ScrollViewer>
            <Canvas Width="200" Height="130" Focusable="False" IsEnabled="False" IsHitTestVisible="False">
                <Canvas.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="#FFFFFFFF" Offset="0" />
                        <GradientStop Color="#00FFFFFF" Offset="0.1" />
                        <GradientStop Color="#00FFFFFF" Offset="0.9" />
                        <GradientStop Color="#FFFFFFFF" Offset="1" />
                    </LinearGradientBrush>
                </Canvas.Background>
            </Canvas>
        </Grid>

目的の効果を確認しやすいように、ScrollViewer に背景色を追加し、TextBlock に大きな上部マージンを追加しました。出力は次のようになります。 代替テキスト

于 2009-12-14T17:52:21.013 に答える
1

私は今日同じ問題に直面しましたが、解決策は実際には非常に簡単です.ScrollViewer.Backgroundプロパティをnull以外に設定すると(あなたの場合はTransparentが必要です)、うまくいきます。

この問題に関して私が見つけた唯一の質問であるため、ここに回答を投稿しています。

于 2010-08-25T15:25:47.297 に答える
1

アントワーヌは、後ろ向きであることを除けば正しい。テキストブロックの背景色を白または透明、または必要なものに設定する必要があります。

 <Grid Background="LightGray">
    <ScrollViewer BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2"
                       HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden" >
        <ScrollViewer.OpacityMask>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0" />
                <GradientStop Color="Black" Offset="0.1" />
                <GradientStop Color="Black" Offset="0.9" />
                <GradientStop Color="Transparent" Offset="1" />
            </LinearGradientBrush>
        </ScrollViewer.OpacityMask>
        <TextBlock Margin="0,10"  TextWrapping="Wrap" Width="200" Background="White">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
        </TextBlock>
    </ScrollViewer>
</Grid>

TextBlock の背景を削除すると、textblock 内のテキストがフェードアウトしますが、背景が定義されていると、スクロールビューアにのみ適用されます。

于 2013-04-16T22:37:09.543 に答える