如何滚动以便在展开 Expander 后控件可见

mer*_*ger 2 c# wpf xaml

我在 wpf 用户控件中有几个 Expander 控件。当我展开扩展器时,我想自动滚动,以便整个扩展器可见(如果可能)。或者至少让新扩展的 Expander 尽可能“向上”。

当我现在在底部执行此操作时,它会扩展到窗口边缘下方,并且如果不手动滚动到扩展器中的控件,我将无法看到它们。

我想从 XAML 而不是代码隐藏中执行此操作。这可能吗?我使用 MVVM 模式。

我假设我必须在 Expander 上使用触发器,但我不知道如何执行 BringToView 功能

高层布局:

<ScrollViewer>
  <UserControl>
    <Grid>
      <Expander>
        ...
      </Expander>
      <Expander>
        ...
      </Expander>
      <Expander>
        ...
      </Expander>
    </Grid>
  </UserControl>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

Ron*_*Ron 5

处理Expanded事件和调用BringIntoView()方法:

private void Expander_Expanded(object sender, RoutedEventArgs e)
{
    ((Expander)sender).BringIntoView();
}
Run Code Online (Sandbox Code Playgroud)

请注意,您应该使用 StackPanel 或其他东西来代替Grid

<ScrollViewer Name="sv">
    <UserControl>
        <StackPanel>
            <Expander>
                <Border Height="1000" Background="Red"/>
            </Expander>
            <Expander>
                <Border Height="1000" Background="Blue"/>
            </Expander>
            <Expander Expanded="Expander_Expanded">
                <Border Height="1000" Background="Green"/>
            </Expander>
        </StackPanel>
    </UserControl>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

编辑

您可能想使用此附加属性:

public static class ExpanderEx
{
    public static readonly DependencyProperty BringIntoViewOnExpandProperty =
                           DependencyProperty.RegisterAttached("BringIntoViewOnExpand", 
                                typeof(bool), typeof(ExpanderEx), 
                                new PropertyMetadata(false, OnBringIntoViewOnExpandChanged));


    public static bool GetBringIntoViewOnExpand(DependencyObject obj)
    {
        return (bool)obj.GetValue(BringIntoViewOnExpandProperty);
    }
    public static void SetBringIntoViewOnExpand(DependencyObject obj, bool value)
    {
        obj.SetValue(BringIntoViewOnExpandProperty, value);
    }  
    private static void OnBringIntoViewOnExpandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is Expander)
        {
            Expander obj = (Expander)d;
            if (e.NewValue.Equals(true)) 
                obj.Expanded += Obj_Expanded; 
            else
                obj.Expanded -= Obj_Expanded;
        }
    }

    private static void Obj_Expanded(object sender, RoutedEventArgs e)
    {
        ((Expander)sender).BringIntoView();
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Xaml 中:

<ScrollViewer Name="sv">
    <UserControl>
        <StackPanel>
            <Expander local:ExpanderEx.BringIntoViewOnExpand="True">
                <Border Height="1000" Background="Red"/>
            </Expander>
            <Expander local:ExpanderEx.BringIntoViewOnExpand="True">
                <Border Height="1000" Background="Blue"/>
            </Expander>
            <Expander local:ExpanderEx.BringIntoViewOnExpand="True">
                <Border Height="1000" Background="Green"/>
            </Expander>
        </StackPanel>
    </UserControl>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)