programing

스크롤 뷰어의 하위 요소가 마우스 휠로 스크롤하지 못하게 합니까?

minimums 2023. 4. 28. 20:25
반응형

스크롤 뷰어의 하위 요소가 마우스 휠로 스크롤하지 못하게 합니까?

마우스 휠 스크롤이 다음 XAML에서 작동하는 데 문제가 있습니다. 이 XAML은 명확하게 하기 위해 단순화했습니다.

<ScrollViewer
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
CanContentScroll="False"
>
    <Grid
    MouseDown="Editor_MouseDown"
    MouseUp="Editor_MouseUp"
    MouseMove="Editor_MouseMove"
    Focusable="False"
    >
        <Grid.Resources>
            <DataTemplate
            DataType="{x:Type local:DataFieldModel}"
            >
                <Grid
                Margin="0,2,2,2"
                >
                    <TextBox
                    Cursor="IBeam"
                    MouseDown="TextBox_MouseDown"
                    MouseUp="TextBox_MouseUp"
                    MouseMove="TextBox_MouseMove"
                    />
                </Grid>
            </DataTemplate>
        </Grid.Resources>
        <ListBox
        x:Name="DataFieldListBox"
        ItemsSource="{Binding GetDataFields}"
        SelectionMode="Extended"
        Background="Transparent"
        Focusable="False"
        >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemContainerStyle>
                <Style
                TargetType="ListBoxItem"
                >
                    <Setter
                    Property="Canvas.Left"
                    Value="{Binding dfX}"
                    />
                    <Setter
                    Property="Canvas.Top"
                    Value="{Binding dfY}"
                    />
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</ScrollViewer>

시각적으로, 결과는 알려진 크기의 영역입니다.DataField컬렉션의 읽기는 다음과 같이 나타낼 수 있습니다.TextBox위치, 크기 등이 임의인 경우.다음과 같은 경우.ListBox스타일 "영역"이 너무 커서 한 번에 모두 표시할 수 없습니다. 가로 및 세로 스크롤이 가능하지만 스크롤 막대가 있어야 합니다.

더 나은 인체공학과 제정신을 위해 마우스 휠 스크롤이 가능해야 하며, 일반적으로ScrollViewer자동으로 처리하겠지만, 하지만.ListBox부모가 그런 사건들을 전달하고 있는 것처럼 보입니다.ScrollViewer그들을 보지 못합니다.지금까지 휠 스크롤만 설정할 수 있었습니다.IsHitTestVisible=False둘 중 하나를 위하여ListBox또는 부모Grid물론 그 이후에는 자식 요소의 마우스 이벤트가 작동하지 않습니다.

무엇을 해야만 안전을 보장할 수 있습니까?ScrollViewer하위 요소를 위해 다른 요소를 보존하면서 마우스 휠 이벤트를 볼 수 있습니까?

편집: 방금 알았습니다.ListBox기본 제공됨ScrollViewer아마도 부모로부터 휠 이벤트를 훔치는 것일 것입니다.ScrollViewer제어 템플릿을 지정하면 비활성화할 수 있습니다.문제가 해결되면 이 질문을 업데이트하겠습니다.

또한 동작을 생성하여 스크롤 이벤트가 버블 통과해야 하는 상위 컨트롤에 연결할 수 있습니다.

// Used on sub-controls of an expander to bubble the mouse wheel scroll event up 
public sealed class BubbleScrollEvent : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;
        base.OnDetaching();
    }

    void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        e.Handled = true;
        var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
        e2.RoutedEvent = UIElement.MouseWheelEvent;
        AssociatedObject.RaiseEvent(e2);
    }
}

<SomePanel>
            <i:Interaction.Behaviors>
                <viewsCommon:BubbleScrollEvent />
            </i:Interaction.Behaviors>
</SomePanel>

지정ControlTemplate를 위해Listbox그것은 포함하지 않습니다.ScrollViewer문제를 해결합니다.자세한 내용은 이 답변과 다음 두 MSDN 페이지를 참조하십시오.

컨트롤 템플릿

목록 상자 스타일 및 템플릿

이를 구현하는 또 다른 방법은 다음과 같이 사용자 자신의 ScrollViewer를 만드는 것입니다.

public class MyScrollViewer : ScrollViewer
{
    protected override void OnMouseWheel(MouseWheelEventArgs e)
    {
        var parentElement = Parent as UIElement;
        if (parentElement != null)
        {
            if ((e.Delta > 0 && VerticalOffset == 0) ||
                (e.Delta < 0 && VerticalOffset == ScrollableHeight))
            {
                e.Handled = true;

                var routedArgs = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
                routedArgs.RoutedEvent = UIElement.MouseWheelEvent;
                parentElement.RaiseEvent(routedArgs);
            }
        }

        base.OnMouseWheel(e);
    }
}

조금 늦었지만 저에게 효과가 있었던 다른 해결책이 있습니다.스택 패널/목록 상자를 항목 제어/그리드로 전환했습니다.스크롤 이벤트가 제대로 작동하는 이유는 모르겠지만 제 경우에는 작동합니다.

<ScrollViewer VerticalScrollBarVisibility="Auto" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
                <StackPanel Orientation="Vertical">
                    <ListBox ItemsSource="{Binding DrillingConfigs}" Margin="0,5,0,0">
                        <ListBox.ItemTemplate>
                            <DataTemplate>

되었다

<ScrollViewer VerticalScrollBarVisibility="Auto" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ItemsControl ItemsSource="{Binding DrillingConfigs}" Margin="0,5,0,0" Grid.Row="0">
            <ItemsControl.ItemTemplate>
                <DataTemplate>

isHitTestVisible=아이의 거짓은 나에게 잘 작동합니다.

편집 이것은 좋은 방법이 아닙니다.

언급URL : https://stackoverflow.com/questions/14348517/child-elements-of-scrollviewer-preventing-scrolling-with-mouse-wheel

반응형