Получить ссылку на ScrollViewer моего WPF ListBox в C #? - PullRequest
3 голосов
/ 19 октября 2010

Я думаю, что это должно быть легко, но мне тяжело с этим.

Как я могу получить ссылку на просмотрщик моего ListBox в C #?Я перепробовал почти все, что мог придумать.ListBox находится в пользовательском элементе управления WPF, поэтому мы используем Template.FindName для получения ссылок на все наши элементы управления.Мой ListBox выглядит следующим образом:

<ListBox x:Name="PART_SoundList" 
                                 ScrollViewer.CanContentScroll="False" 
                                 ScrollViewer.HorizontalScrollBarVisibility="Auto"  
                                 ScrollViewer.VerticalScrollBarVisibility="Hidden" Focusable="False" FocusVisualStyle="{x:Null}"
                                 HorizontalAlignment="Center" VerticalAlignment="Bottom"  BorderThickness="0" 
                                 ItemContainerStyleSelector="{StaticResource ListBoxItemAlternatingStyleSelector}"
                                 ItemsSource="{Binding}"  >

                                    <ListBox.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <WrapPanel Orientation="Vertical"  Height="850" Focusable="False" Panel.ZIndex="999"  >
                                                <WrapPanel.RenderTransform>
                                                        <TransformGroup>
                                                            <ScaleTransform CenterX="0" CenterY="0" ScaleX=".75" ScaleY=".57" />
                                                        </TransformGroup>
                                                    </WrapPanel.RenderTransform>
                                            </WrapPanel>
                                        </ItemsPanelTemplate>
                                    </ListBox.ItemsPanel>

                                    <ListBox.Template>
                                        <ControlTemplate>
                                            <ScrollViewer x:Name="Scroller" VerticalAlignment="Bottom" Focusable="False" Style="{StaticResource HorizontalScroller}"   >
                                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Focusable="False" Panel.ZIndex="999"  />
                                            </ScrollViewer>
                                        </ControlTemplate>
                                    </ListBox.Template>

                                </ListBox>

Template.FindName ("Scroller", this), так как ScrollViewer приводит к нулю.

Есть идеи?

Ответы [ 6 ]

5 голосов
/ 19 октября 2010

Возможно, вы пытаетесь получить ссылку на ScrollViewer слишком рано.Попробуйте переместить свой код в загруженное событие и проверьте, возвращает ли он все еще null:

в конструкторе customControl / form:

this.Loaded += MainWindow_Loaded;

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
   var x = PART_SoundList.Template.FindName("Scroller", PART_SoundList);
}
2 голосов
/ 19 октября 2010

Я предполагаю, что XAML, который вы имеете выше, является частью ControlTemplate для вашего CustomControl, верно?Я также предположил бы, что вы получаете контрольные части для метода OnApplyTemplate (), верно?Если это так, то, я думаю, вам нужно вызвать вызов PART_SoundList.ApplyTemplate () перед поиском ScrollViewer.Итак, код для вашего пользовательского элемента управления должен выглядеть примерно так:

public class MyControl : Control
{
    private ListBox lb;
    private ScrollViewer scroller;

    static MyControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        lb = this.Template.FindName("PART_SoundList", this) as ListBox;
        lb.ApplyTemplate();
        scroller = lb.Template.FindName("Scroller", lb) as ScrollViewer;
    }
}
2 голосов
/ 19 октября 2010

Используйте рекурсивный вызов Visual Tree, чтобы получить любой Visual из дерева.

public static ChildItem FindVisualChild<childItem>(DependencyObject obj) where ChildItem : DependencyObject

        {

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)

            {

                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child != null && child is ChildItem)

                    return (ChildItem)child;

                else

                {

                    ChildItem childOfChild = FindVisualChild<ChildItem>(child);

                    if (childOfChild != null)

                        return childOfChild;

                }

            }

            return null;

        }

Это дает вам универсальный метод для получения визуального элемента типа, упомянутого из визуального дерева.

0 голосов
/ 04 июля 2018

Используйте это для доступа к просмотру прокрутки в WPF.

var scrollViewer = ((Граница) PlaybackDeviceList.Template.FindName ("Bd", PlaybackDeviceList)). Child;

0 голосов
/ 26 мая 2016

Для тех, кто попал сюда и ищет ответ на оригинальный вопрос:

В C #

ScrollViewer sv = FindVisualChild<ScrollViewer>(MyListBox);

или в VB

Dim sv As ScrollViewer = FindVisualChild(Of ScrollViewer)(MyListBox)

Где в XAML

<ListBox x:Name="MyListBox">
</ListBox>
0 голосов
/ 19 октября 2010

Если вы собираетесь использовать ссылку для прокрутки / проверки размера области просмотра, вам достаточно IScrollProvider .

Вы можете получить к нему доступ таким образом в своем коде (обратите внимание на точку ожидания Клаудиу до загруженного события):

ListBoxAutomationPeer svAutomation = (ListBoxAutomationPeer)ScrollViewerAutomationPeer.CreatePeerForElement(PART_SoundList);
// not feeling creative with my var names today...
IScrollProvider scrollInterface = (IScrollProvider)svAutomation.GetPattern(PatternInterface.Scroll);

Затем прокручивайте по горизонтали и вертикали, когда захотите, и в соответствии с вашими сердцами.

...