【问题标题】:Can i disable scrollviewer from within?我可以从内部禁用滚动查看器吗?
【发布时间】:2016-12-20 18:49:11
【问题描述】:

我有一个列表框,但我无法修复标题,因此它不会随着页面的其余部分滚动。 找了原因,发现在主窗口,通过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>

问题是,这个滚动查看器不起作用,因为它周围有一个更高级别的包裹,我无法得到......

【问题讨论】:

  • 你能告诉我们什么是标题吗?你想怎么解决?

标签: c# wpf xaml


【解决方案1】:

也许您可以调整内容的大小,使周围的ScrollViewer 没有理由提供滚动。相反,通过限制 ListBox 的高度来提供滚动:

<!-- 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 作为高度。当然,这应该替换为您想要的高度。如果您希望它是动态的,您可以使用Multibinding 到StackPanel 和TextBlock 的ActualHeight 和一个转换器返回(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。同样,这应该替换为您想要的高度。如果您希望它是动态的,您可以使用Multibinding 到Grid 和StackPanel 的ActualHeight 和一个转换器返回(Grid 的ActualHeight)-(StackPanel 的ActualHeight) .
  • 为Grid 的Height 添加了Binding

【讨论】:

    【解决方案2】:

    由于我找不到方法,我建议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>
    

    【讨论】:

      【解决方案3】:

      是否可以在我的窗口中禁用此 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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2010-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-23
        • 2017-09-29
        • 1970-01-01
        相关资源
        最近更新 更多