WPF Scroll & проблема изменения фокуса - PullRequest
3 голосов
/ 10 мая 2011

У меня проблема с прокруткой для моего приложения WPF.

Вот предложение.Мой пользовательский интерфейс выглядит следующим образом:

ScrollViewer

Роль моего приложения заключается в том, чтобы выступать в качестве центрального концентратора для многих приложений и запускать их.Администратор может запустить дамп, записанный другим пользователем.Поэтому у меня есть ListView, показывающий список приложений, который можно прокручивать при необходимости.Я определил GroupStyle, чтобы показать расширители и эмулировать представление Windows Explorer.Все работает нормально, у меня просто проблема: при прокрутке колесиком мыши компонент синего цвета («Режим запуска»), кажется, ловит фокус и останавливает прокрутку.Особенно это означает, что если моя мышь находится вне этого контроля, прокрутка в порядке.Но когда мышь входит в этот элемент управления, я больше не могу прокручивать.Я попытался изменить свойство Focusable и установить его на False везде, где мог, но ничего не изменилось.Я предполагаю, что это, наконец, не проблема фокуса.У кого-нибудь есть идеи о том, как избежать прокрутки, которая может быть захвачена элементом?

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

<StackPanel Orientation="Vertical"  VerticalAlignment="Top" >

            <ToggleButton>
                <!-- ToggleButton Content... -->
            </ToggleButton>

            <!-- This is the custom component in which you can see "Launch mode" -->
            <my:UcReleaseChooser >
                <!-- Properties there. I tried to set Focusable to False, no impact... -->
            </my:UcReleaseChooser>

        </StackPanel>

И код для UcReleaseChooser:

<StackPanel HorizontalAlignment="Stretch"
                Focusable="False" ScrollViewer.CanContentScroll="False">

        <ListBox ItemsSource="{Binding ListChosenReleases}" BorderBrush="LightGray" Background="AliceBlue"
                 HorizontalAlignment="Stretch" Focusable="False" ScrollViewer.CanContentScroll="False">

            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical" 
                                Focusable="False" ScrollViewer.CanContentScroll="False"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel LastChildFill="True" HorizontalAlignment="Stretch"
                               Focusable="False" ScrollViewer.CanContentScroll="False">
                        <TextBlock DockPanel.Dock="Top"
                            HorizontalAlignment="Left" Text="{Binding Key}" 
                                   FontStyle="Italic"/>
                        <ListBox DockPanel.Dock="Bottom"
                            HorizontalAlignment="Right" ItemsSource="{Binding Value}"
                                 BorderBrush="{x:Null}" Background="AliceBlue"
                                 Focusable="False" ScrollViewer.CanContentScroll="False">
                            <ListBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <UniformGrid Focusable="False"/>
                                </ItemsPanelTemplate>
                            </ListBox.ItemsPanel>

                            <ListBox.ItemContainerStyle>
                                <Style TargetType="{x:Type ListBoxItem}">
                                    <-- Blah blah about style -->
                                </Style>
                            </ListBox.ItemContainerStyle>


                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <RadioButton Content="{Binding Key}" Margin="3"
                                            IsChecked="{Binding Path=IsSelected, Mode=TwoWay, 
                                                        RelativeSource={RelativeSource FindAncestor, 
                                                            AncestorType={x:Type ListBoxItem}}}" 
                                                 Focusable="False" ScrollViewer.CanContentScroll="False"/>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>

        </ListBox>

    </StackPanel>

Как видите, UcReleaseChooser содержит список RadioButton списков.Я пытался установить Focusable & CanContentScroll на False везде, где это казалось уместным, но элемент управления продолжает препятствовать прокрутке основного интерфейса ...

Я думаю, мне следует изменить другое свойство ... Любоеидея?

Спасибо!

Ответы [ 2 ]

1 голос
/ 22 октября 2014

У меня была проблема со списком, крадущим фокус внутри средства просмотра прокрутки (у меня есть несколько списков внутри средства просмотра прокрутки). Поэтому я создал прикрепленное свойство, которое лишает список возможности прокрутки. Поэтому прокручиватель, в котором находится список, может прокручивать

Ваш элемент управления является списком, поэтому он должен работать как есть, но нет никаких причин, по которым расширение должно быть ограничено списком; это просто соответствует моей точной цели.

 public static class ListboxExtensions
{
    public static DependencyProperty IgnoreScrollProperty = DependencyProperty.RegisterAttached("IgnoreScroll", typeof(bool), typeof(ListboxExtensions), new UIPropertyMetadata(false, IgnoreScrollChanged));

    public static bool GetIgnoreScroll(DependencyObject dependencyObject)
    {
        return (bool)dependencyObject.GetValue(IgnoreScrollProperty);
    }

    public static void SetIgnoreScroll(DependencyObject dependencyObject, bool value)
    {
        dependencyObject.SetValue(IgnoreScrollProperty, value);
    }

    private static void IgnoreScrollChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var newValue = (bool)e.NewValue;
        var oldValue = (bool)e.OldValue;

        var frameworkElement = d as FrameworkElement;
        if (frameworkElement == null) return;

        if (!newValue || oldValue || frameworkElement.IsFocused) return;

        var lb = frameworkElement as ListBox;
        if (lb == null) return;

        lb.PreviewMouseWheel += LbOnPreviewMouseWheel;
    }

    private static void LbOnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (!(sender is ListBox) || e.Handled) return;

        e.Handled = true;
        var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
            {
                RoutedEvent = UIElement.MouseWheelEvent,
                Source = sender
            };

        var parent = ((Control)sender).Parent as UIElement;
        if (parent != null) parent.RaiseEvent(eventArg);
    }
}

И затем в вашем XAML вы просто помещаете это в список:

 <ListBox extensions:ListboxExtensions.IgnoreScroll="True">

Конечно, не забывая включать пространство имен в свои расширения в верхней части XAML:

xmlns:extensions="clr-namespace:UI.Extensions"
1 голос
/ 10 мая 2011

Проблема в ListBox или, точнее, ScrollViewer в шаблоне ListBox. Это получает ваши события прокрутки и использует их до того, как внешний ScrollViewer в ListView даже увидит их.

Я бы посоветовал заменить ListBox на ItemsControl, если это возможно. Однако это подразумевает, что свойства SelectedItem не будет. Если вам это нужно, я бы предложил установить ScrollViewer.HorizontalScrollBarVisibility (или VerticalScrollBarVisibility) на Disabled. В противном случае я могу только предложить повторно шаблон ListBox, чтобы вообще не содержать ScrollViewer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...