C# Scrollviewer正在自动向下滚动

C# Scrollviewer正在自动向下滚动,c#,wpf,listbox,devexpress,scrollviewer,C#,Wpf,Listbox,Devexpress,Scrollviewer,我的列表框(普通WPF,System.Windows.Controls.ListBox)中的项目本身包含列表框(也是普通WPF)时出现问题。在我的生产应用程序(使用DevExpress控件)中,当创建外部列表框时,它会立即向下滚动(但可见),以便最后一个内部列表框中的第一项可见 我尝试用一个不带DevXPress和使用DevXPress的最小应用程序重现这种行为。两者都没有表现出这种行为 我已将处理程序附加到(外部)ListBox的ScrollViewer的ScrollChanged,我看到了导

我的
列表框
(普通WPF,
System.Windows.Controls.ListBox
)中的项目本身包含
列表框
(也是普通WPF)时出现问题。在我的生产应用程序(使用DevExpress控件)中,当创建外部<代码>列表框时,它会立即向下滚动(但可见),以便最后一个内部<代码>列表框中的第一项可见

我尝试用一个不带DevXPress和使用DevXPress的最小应用程序重现这种行为。两者都没有表现出这种行为

我已将处理程序附加到(外部)
ListBox
ScrollViewer
ScrollChanged
,我看到了导致滚动的事件,但我无法确定它的来源

旁注:如果我将
列表框
中的一个(无论是内部还是外部)设为DevExpress-
列表框编辑
,滚动问题就会消失。但是,我不能这样做,因为当我单击项目时,我得到了有关集合在枚举期间更改的
invalidoOperationException
s。我不需要也不想要
ListBoxEdit
功能

第二个旁注:我已尝试删除外部
列表框的主题(
themanager.ThemeName=“None”
),但没有效果

所以问题是,我如何才能找出是谁导致了滚动(以防止他这样做)

更新:聚焦外部列表框的第一项不会改变任何东西

更新:订阅
RequestBringIntoView
并设置
Handled=true
可以解决问题,但前提是我在那里打断了。没有断点,它什么也不做。stacktrace本身没有告诉我任何事情:

bei MyApp.MyAppControls.BackToToTopListBox.OnRequestBringIntoView(Object sender, RequestBringIntoViewEventArgs requestBringIntoViewEventArgs)
bei System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
bei System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
bei System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
bei System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
bei System.Windows.Controls.ScrollViewer.ExecuteNextCommand()
bei System.Windows.Controls.ScrollViewer.OnLayoutUpdated(Object sender, EventArgs e)
bei System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
bei System.Windows.ContextLayoutManager.UpdateLayout()
bei System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
bei System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
bei System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
bei System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
bei MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Windows.Threading.DispatcherOperation.Invoke()
bei System.Windows.Threading.Dispatcher.ProcessQueue()
bei System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
bei System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
bei System.Windows.Application.RunDispatcher(Object ignore)
bei System.Windows.Application.RunInternal(Window window)
bei MyApp.MAT.App.Main()

通过将ScrollViewer的控件模板更改为更简单的内容,可以从列表框中删除ScrollViewer:

<ListBox>
    <ListBox.Template>
        <ControlTemplate>
            <ItemsPresenter />
        </ControlTemplate>
    </ListBox.Template>
    ...
</ListBox>

...
然而,我质疑嵌套列表框的价值。请记住,每个列表框都是一个选择器,并且有一个“选中”项目的概念。把一个选中的项目放在选中的项目里面,放在选中的项目里面,真的有意义吗


我建议将“内部”列表框更改为简单的ItemsControl,这样嵌套列表就不能包含选定的项。这将带来更简单的用户体验。您可能仍然需要以相同的方式重新配置内部Items控件以删除滚动条,但至少用户不会对“已选择”的项目感到困惑。

您可以通过阻止ListBoxItem的RequestBringIntoView事件来防止自动滚动

<ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <EventSetter Event="RequestBringIntoView" Handler="ListBoxItem_RequestBringIntoView"/>
            </Style>
        </ListBox.ItemContainerStyle>

void ListBoxItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
    e.Handled = true;
}

void ListBoxItem_RequestBringIntoView(对象发送方,RequestBringIntoViewEventArgs e)
{
e、 已处理=正确;
}

您可能想强调一下,您所说的是标准WPF列表框,这在第一次阅读时并不清楚。使用DevExpress,可以查看重点项目,也许最后一个列表框会发生什么情况?要删除主题,您可以查看一下。没有一个项目被选中,也没有一个项目应该被聚焦,但我将对此进行调查。关于主题,我已尝试从整个应用程序或从外部列表框或仅从内部列表框中删除主题,但这并没有解决问题。要从列表中删除DevExpress,您可以进一步删除它,并通过设置显式样式(这不是BasedOn)覆盖任何(独立于主题的)隐式样式在每个列表框上。问题:1。如果将ScrollViewer.CanContentScroll设置为false,并且没有停止您的行为2,会发生什么情况。如果禁用,会发生什么IsSynchronizedWithCurrentItem@Nebelkraehe
CanContentScroll=true
解决了这个问题,但我失去了平滑滚动
IsSynchronizedWithCurrentItem=False没有任何区别。我无法删除scrollviewer,我希望它能够滚动,只是不能在创建时立即滚动。