Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

滚动视图:Scrollviwer 或者 listview 等, 可以添加一个 滚动到选中view 的 附加属性吗? #172

Open
heartacker opened this issue Jun 3, 2023 · 1 comment

Comments

@heartacker
Copy link

大概是这个意思:
https://mattduffield.wordpress.com/2011/01/15/automatically-scrolling-to-a-selected-item-in-a-scrollviewer-in-silverlight/

@Hakoyu
Copy link

Hakoyu commented Aug 16, 2023

我之前好像写了个差不多的 你可以用用
需要 Behaviors

public class ScrollToControlAction : TriggerAction<FrameworkElement>
{
    public static readonly DependencyProperty ScrollViewerProperty = DependencyProperty.Register(
        "ScrollViewer",
        typeof(ScrollViewer),
        typeof(ScrollToControlAction)
    );

    public static readonly DependencyProperty TargetControlProperty = DependencyProperty.Register(
        "TargetControl",
        typeof(FrameworkElement),
        typeof(ScrollToControlAction)
    );

    public ScrollViewer ScrollViewer
    {
        get => (ScrollViewer)GetValue(ScrollViewerProperty);
        set => SetValue(ScrollViewerProperty, value);
    }

    public FrameworkElement TargetControl
    {
        get => (FrameworkElement)GetValue(TargetControlProperty);
        set => SetValue(TargetControlProperty, value);
    }

    protected override void Invoke(object parameter)
    {
        if (TargetControl is null || ScrollViewer is null)
            throw new ArgumentNullException($"{ScrollViewer} or {TargetControl} cannot be null");
        // 检查指定的控件是否在指定的 ScrollViewer 中
        var result = TargetControl.FindVisuaParent<ScrollViewer>();
        if (result is null || result != ScrollViewer)
            throw new Exception("The TargetControl is not in the target ScrollViewer");

        // 获取要定位之前 ScrollViewer 目前的滚动位置
        var currentScrollPosition = ScrollViewer.VerticalOffset;
        var point = new Point(0, currentScrollPosition);

        // 计算出目标位置并滚动
        var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point);
        ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);
    }

    public static T FindVisuaParent<T>(this DependencyObject reference)
        where T : DependencyObject
    {
        var temp = reference;
        while ((temp = VisualTreeHelper.GetParent(temp)) is not null)
        {
            if (temp is T t)
                return t;
        }
        return null!;
    }
}

示例

  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" MinWidth="100" />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <StackPanel>
      <Button Content="1">
        <i:Interaction.Triggers>
          <i:EventTrigger EventName="Click">
            <local:ScrollToControlAction ScrollViewer="{Binding ElementName=ScrollViewer}" TargetControl="{Binding ElementName=Button_4}" />
          </i:EventTrigger>
        </i:Interaction.Triggers>
      </Button>
    </StackPanel>
    <ScrollViewer
      x:Name="ScrollViewer"
      Grid.Column="1"
      VerticalScrollBarVisibility="Auto">
      <StackPanel>
        <Button Height="100" Content="111" />
        <Button Height="100" Content="222" />
        <Button Height="100" Content="333" />
        <Button
          x:Name="Button_4"
          Height="100"
          Content="444" />
        <Button
          x:Name="Button_5"
          Height="100"
          Content="555" />
      </StackPanel>
    </ScrollViewer>
  </Grid>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants