簡體   English   中英

我可以從內部禁用scrollviewer嗎?

[英]Can i disable scrollviewer from within?

我有一個ListBox,但我無法修復標題,因此它不會與頁面的其余部分一起滾動。 搜索原因后,我發現在通過ContentControl放置所有內容的主窗口中,有一個ScrollViewer包裹着所有內容:

<ScrollViewer Margin="0,0,0,0" >   
    <ContentControl x:Name="content" Margin="0,0,0,0"/>
</ScrollViewer>

我無法真正刪除它,因為我只在一個內容頁面上工作,該頁面稍后將在該項目中實現。 是否可以從我的窗口中禁用此ScrollViewer? 還是以某種方式使其不再影響我的內容?

編輯:要明確。 這段代碼(上面)在MainWindow中,我無法編輯。 內容通過content.Content = new (content class)在.cs中添加。 在我正在研究的其中一門課程中,我有:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="20" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="1" Orientation="Horizontal">
        <TextBlock Text ={x:Static ...}>
        <Text Block ...>
    </StackPanel>           

    <ScrollViewer Grid.Row="2">
        <ListBox>...</ListBox>
    </ScrollViewer>
</Grid>

問題是,這個scrollviewer不能正常工作,因為有一個包裝在更高的層次上,我無法獲得……

也許您可以通過周圍ScrollViewer沒有理由提供滾動的方式來調整內容的大小。 而是通過限制列表框的高度來滾動列表框:

<!-- When the StackPanel is not bigger than the ScrollViewer, there should be no reason for it to scroll your title out of sight. If there is Padding in your scroll viewer, an additional converter may bre required to modify the height accordingly -->
<StackPanel Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}}">
    <TextBlock Text="TitleForMyListBox"/>
    <ListBox Height="50">
        <!-- ... -->
    </ListBox>
</StackPanel>

我用50作為高度。 當然,應將其替換為所需的高度。 如果您希望它是動態的,則可以對StackPanelTextBlockActualHeight使用Multibinding ,並使用返回( StackPanel ActualHeight )-( TextBlock ActualHeight )的轉換器。

編輯:將其應用於您編輯中的代碼:

<Grid Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}}">
    <Grid.RowDefinitions>
        <RowDefinition Height="20" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Orientation="Horizontal">
        <TextBlock Text ={x:Static ...}>
        <Text Block ...>
    </StackPanel>           

    <ListBox Grid.Row="1">...</ListBox>
</Grid>

我有:

  • 固定Grid.Row數字
  • 刪除了ScrollViewer因為ListBox將在其高度受到限制時提供滾動
  • ListBox的高度限制為50。同樣,應將其替換為所需的高度。 如果希望它是動態的,則可以對GridStackPanelActualHeight進行Multibinding ,並使用返回( Grid ActualHeight )-( StackPanel ActualHeight )的轉換器。
  • 添加了Grid HeightBinding

由於我找不到執行此操作的方法,因此我建議使用此AttachedProperty 您可以使用此AttachedProperty禁用ParentView ScrollViewer 。這是實現要求的一種方法。

 public class ScrollViewerExtension : DependencyObject
{

    public static bool GetDisableParentScrollViewer(DependencyObject obj)
    {
        return (bool)obj.GetValue(DisableParentScrollViewerProperty);
    }

    public static void SetDisableParentScrollViewer(DependencyObject obj, bool value)
    {
        obj.SetValue(DisableParentScrollViewerProperty, value);
    }

    // Using a DependencyProperty as the backing store for DisableParentScrollViewer.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DisableParentScrollViewerProperty =
        DependencyProperty.RegisterAttached("DisableParentScrollViewer", typeof(bool), typeof(ScrollViewerExtension), new PropertyMetadata(false,OnDisableParentScrollViewerChanged));

    private static void OnDisableParentScrollViewerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FrameworkElement)
        {
            (d as FrameworkElement).Loaded += (_, __) =>
              {
                  var scrollViewer = FindAncestor(d as Visual, typeof(ScrollViewer)) as ScrollViewer;
                  if (scrollViewer != null && (bool)e.NewValue)
                      scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
              };
        }
    }

    public static Visual FindAncestor(Visual startingFrom, Type typeAncestor)
    {
        if (startingFrom != null)
        {
            DependencyObject parent = VisualTreeHelper.GetParent(startingFrom);

            while (parent != null && !typeAncestor.IsInstanceOfType(parent))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            return parent as Visual;
        }

        return null;
    }
}

在您看來,

<Grid attached:ScrollViewerExtension.DisableParentScrollViewer="True">
<Grid.RowDefinitions>
    <RowDefinition Height="20" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Orientation="Horizontal">
    <TextBlock Text ={x:Static ...}>
    <Text Block ...>
</StackPanel>           

<ScrollViewer Grid.Row="2">
    <ListBox>...</ListBox>
</ScrollViewer>

是否可以從我的窗口中禁用此ScrollViewer? 還是以某種方式使其不再影響我的內容?

您可以處理控件的Loaded事件,在視覺樹中找到父級ScrollViewer並使用ScrollViewer.SetVerticalScrollBarVisibility方法禁用它。

Window.xaml:

<Window x:Class="WpfApplication1.Window14"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="Window14" Height="300" Width="300">
    <Grid>
        <ScrollViewer Margin="0,0,0,0" Height="200" >
            <ContentControl x:Name="content" Margin="0,0,0,0">
                <ContentControl.Content>
                    <local:UserControl1 />
                </ContentControl.Content>
            </ContentControl>
        </ScrollViewer>
    </Grid>
</Window>

UserControl1.xaml:

<UserControl x:Class="WpfApplication1.UserControl2"
             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:local="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" Background="Yellow" ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Rectangle Height="100" Fill="Green" />
        <ListBox x:Name="lv" Grid.Row="1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

UserControl1.xaml.cs:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        this.Loaded += UserControl1_Loaded;
        lv.ItemsSource = Enumerable.Range(0, 1000);
    }

    private void UserControl1_Loaded(object sender, RoutedEventArgs e)
    {
        ScrollViewer sv = FindParent<ScrollViewer>(this);
        if (sv != null)
        {
            ScrollViewer.SetVerticalScrollBarVisibility(sv, ScrollBarVisibility.Disabled);
        }
    }

    private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);

        if (parent == null) return null;

        var parentT = parent as T;
        return parentT ?? FindParent<T>(parent);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM