2016-12-20 3 views
1

У меня есть ListBox, но я не смог исправить заголовок, поэтому он не будет прокручиваться вместе с остальной частью страницы. После поиска по причине, я обнаружил, что в главном окне, где все находится через ContentControl, есть один ScrollViewer обернут вокруг всего:Могу ли я отключить scrollviewer изнутри?

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

Я не могу удалить его, потому что я работаю только на одной странице контента, которая позже будет реализована в этом проекте. Можно ли отключить этот ScrollViewer из моего окна? Или каким-то образом заставить его перестать влиять на мой контент?

EDIT: Чтобы было ясно. этот код (выше) находится в MainWindow, который я не могу редактировать. Содержание добавлено в .cs по content.Content = new (content class). В одном из этих классов, которые я работаю, я есть:

<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, потому что есть один завернутые arount его на более высоком уровне, где я не могу получить ...

+0

вы можете сказать нам, что АЭМ дер? как вы хотите это исправить? – WPFUser

ответ

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 к ActualHeight в StackPanel и TextBlock и преобразователь возвращающегося (ActualHeight из StackPanel) - (ActualHeight из TextBlock).

EDIT: Применяя это к коду в вашем редактирования:

<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. Опять же, это s может быть заменена на желаемую высоту. Если вы хотите динамический, вы можете использовать Multibinding к ActualHeight в Grid и StackPanel и преобразователь возвращающегося (ActualHeight из Grid) - (ActualHeight из StackPanel).
  • Добавлен Binding для Height в Grid
1

Поскольку я не могу найти способ сделать это, я предлагаю это AttachedProperty. Вы можете отключить ParentView ScrollViewer с помощью этого AttachedProperty. Это один из способов достижения ваших требований.

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> 

1

Можно ли отключить эту 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); 
    } 
}