Ticket T1287284
Visible to All Users

Make mouse scroll zoom chart controll instead pan scroll viewer

created 12 days ago

Hi,

I'm running into a similar issue as described here
https://supportcenter.devexpress.com/ticket/details/t728102

Except the solution is not working for me.

My view is a bit more complex than just a chart in a scroll viewer.
A slimmed down version, but the big feature is that the grid is filled with views depending on viewmodel.
The ChartControl is in the view of the HeatingControllerView

XAML
<UserControl x:Class="MPTUI.TwinCAT.ContextObject.Views.ContextObjectOverviewView" 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:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:attachedBehaviours="clr-namespace:MPTUI.AttachedBehaviours;assembly=MPTUI" xmlns:services="clr-namespace:MPTUI.TwinCAT.ContextObject.Services" xmlns:viewModels="clr-namespace:MPTUI.TwinCAT.ContextObject.ViewModels" xmlns:twincatConverters="clr-namespace:MPTUI.TwinCAT.Converters" xmlns:heatingViews="clr-namespace:MPTUI.TwinCAT.Heating.Views" xmlns:heatingViewModels="clr-namespace:MPTUI.TwinCAT.Heating.ViewModels" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type=viewModels:ContextObjectOverviewViewModel, IsDesignTimeCreatable=True}"> <UserControl.Resources> <ResourceDictionary Source="pack://application:,,,/MPTUI;component/Styles/StyleDictionary.xaml" /> </UserControl.Resources> <dxmvvm:Interaction.Behaviors> <dx:CurrentDialogService UnregisterOnUnloaded="True" /> </dxmvvm:Interaction.Behaviors> <ScrollViewer dx:ScrollBarExtensions.ScrollBarMode="TouchOverlap" PanningMode="VerticalFirst"> <dxmvvm:Interaction.Behaviors> <attachedBehaviours:ExtendedScrollViewerBehaviour/> </dxmvvm:Interaction.Behaviors> <ScrollViewer.Resources> <DataTemplate DataType="{x:Type heatingViewModels:HeatingControllerViewModel}"> <heatingViews:HeatingControllerView /> </DataTemplate> <DataTemplate x:Key="LConContextObject"> <dxe:ToggleSwitch HorizontalAlignment="Left" Margin="5" IsChecked="{Binding RowData.Row.Enable}" Command="{Binding RowData.Row.ToggleEnableCommand}" /> </DataTemplate> <DataTemplate x:Key="ETrigContextObject"> <dxe:ToggleSwitch HorizontalAlignment="Left" Margin="5" IsChecked="{Binding RowData.Row.Execute}" Command="{Binding RowData.Row.ToggleExecuteCommand}" /> </DataTemplate> <DataTemplate x:Key="EmptyEdit" /> </ScrollViewer.Resources> <dxg:GridControl ItemsSource="{Binding ContextObjectViewModels}" MaxHeight="1440" Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ActualHeight}"> <dxmvvm:Interaction.Behaviors> <dxmvvm:EventToCommand EventName="MasterRowCollapsed" Command="{Binding MasterRowCollapsed}" PassEventArgsToCommand="True" /> <dxmvvm:EventToCommand EventName="MasterRowExpanded" Command="{Binding MasterRowExpanded}" PassEventArgsToCommand="True" /> <dxmvvm:EventToCommand EventName="GroupRowCollapsed" Command="{Binding GroupRowCollapsed}" PassEventArgsToCommand="True" /> </dxmvvm:Interaction.Behaviors> <dxg:GridColumn Header="Name" Binding="{Binding Name}" /> <dxg:GridColumn Header="Status Value" Binding="{Binding StatusValue}" /> <dxg:GridColumn Header="Type" Binding="{Binding TypeName}" GroupIndex="0" Visible="False" /> <dxg:GridColumn Header="Error ID" FieldName="ErrorId" Binding="{Binding ErrorId}" /> <dxg:GridColumn Header="State" Binding="{Binding State, Converter={twincatConverters:StateEnumTranslationConverter}}" /> <dxg:GridColumn Header="Enable/Execute" Binding="{Binding }"> <dxg:GridColumn.CellTemplateSelector> <services:ContextObjectCellTemplateSelectorService /> </dxg:GridColumn.CellTemplateSelector> </dxg:GridColumn> <dxg:GridColumn Header="Instance Path" Binding="{Binding InstancePath}" BestFitModeOnSourceChange="AllRows" /> <dxg:GridControl.View> <dxg:TableView AllowEditing="False" AllowResizing="True" ShowSearchPanelMode="Always" AllowConditionalFormattingMenu="False" ShowGroupPanel="True" FontSize="20" ExpandDetailButtonWidth="50"> <dxg:TableView.FormatConditions> <dxg:FormatCondition ValueRule="NotEqual" Value1="0" FieldName="ErrorId" PredefinedFormatName="LightRedFillWithDarkRedText" /> </dxg:TableView.FormatConditions> </dxg:TableView> </dxg:GridControl.View> <dxg:GridControl.DetailDescriptor> <dxg:ContentDetailDescriptor> <dxg:ContentDetailDescriptor.ContentTemplate> <DataTemplate> <ContentPresenter Content="{Binding}" /> </DataTemplate> </dxg:ContentDetailDescriptor.ContentTemplate> </dxg:ContentDetailDescriptor> </dxg:GridControl.DetailDescriptor> </dxg:GridControl> </ScrollViewer> </UserControl>

As I use the MVVM pattern, a translated the solution provided in the other support ticket to an attached behaviour

C#
public class ExtendedScrollViewerBehaviour : Behavior<ScrollViewer> { protected override void OnAttached() { AssociatedObject.PreviewMouseWheel += AssociatedObjectOnPreviewMouseWheel; } protected override void OnDetaching() { AssociatedObject.PreviewMouseWheel -= AssociatedObjectOnPreviewMouseWheel; } private static void AssociatedObjectOnPreviewMouseWheel(object sender, MouseWheelEventArgs e) { if (e.Source is not Pane pane) { return; } if (pane.Parent is not XYDiagram2D diagram2D) { return; } if (diagram2D.Parent is not ChartControl chartControl) { return; } if (System.Windows.Input.Keyboard.IsKeyDown(Key.LeftShift) || System.Windows.Input.Keyboard.IsKeyDown(Key.RightShift)) { if (e.Delta < 0) ((XYDiagram2D) chartControl.Diagram).ZoomOut(e.GetPosition(chartControl)); else ((XYDiagram2D) chartControl.Diagram).ZoomIn(e.GetPosition(chartControl)); // zoomLocation = Point } else { ((XYDiagram2D) chartControl.Diagram).ScrollHorizontally(e.Delta); } e.Handled = true; } }

However when I hover over the ChartControl with the mouse and zoom, the source it not a pane, but the TableView
Clipboard-File-1.png

So how can I make it work?

Answers approved by DevExpress Support

created 11 days ago

Hello Gerhard,

To resolve the issue, set the ScrollViewer.HandlesDefaultMouseScrolling property to False. For example:

XAML
<ScrollViewer dx:ScrollBarExtensions.HandlesDefaultMouseScrolling="False" PanningMode="VerticalOnly" > <Grid Height="3000"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="5*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <dxc:ChartControl Grid.Row="2" x:Name="chart"> <dxc:XYDiagram2D EnableAxisXNavigation="true" EnableAxisYNavigation="true"> ... </dxc:XYDiagram2D> </dxc:ChartControl> </Grid> </ScrollViewer>

Refer to the answer in this ticket for more details: Zooming of ChartControl when inside ScrollViewer issue

Please let me know if this helps.

Regards,
Steven

    Show previous comments (1)
    SC SC
    Steven Castro (DevExpress Support) 10 days ago

      Hello Gerhard,

      Thank you for your follow-up.

      To resolve the issue, set your Chart Control ScrollBarExtensions.ScrollBehavior property to NativeScrollBehavior. This behavior ensures that the innermost control has scrolling priority. As a result, you'll need to move the mouse cursor outside the Chart Control to scroll the Grid Control. For example:

      XAML
      <dxc:ChartControl> <dx:ScrollBarExtensions.ScrollBehavior> <dx:NativeScrollBehavior /> </dx:ScrollBarExtensions.ScrollBehavior> ... </dxc:ChartControl>

      RnYLKLdyBB.gif

      I attached a sample project for your reference.

      If the solution doesn't work, please share a runnable sample project or modify the attached project to illustrate the issue. This way, I will be in a better position to analyze the issue more efficiently.

      Regards,
      Steven

        Hi Steven,

        Thank you, that gives me the behavior I would expect as and end user.
        Are there additional steps when using touch input instead of mouse input?

        SC SC
        Steven Castro (DevExpress Support) 10 days ago

          Hello Gerhard,

          No, but if you encounter any issues, please don’t hesitate to reach out to us.

          See also: Touch Support

          Regards,
          Steven

          Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

          Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.