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
So how can I make it work?