Laden...

Touch Events / Manipulation Canvas nach MVVM

Erstellt von Boesling vor 2 Jahren Letzter Beitrag vor 2 Jahren 883 Views
B
Boesling Themenstarter:in
4 Beiträge seit 2018
vor 2 Jahren
Touch Events / Manipulation Canvas nach MVVM

Hallo liebe Community,
ich bin gerade dabei eine Anwendung nach MVVM-Pattern umzustellen. In der Anwendung werden diverse Usercontrols und ein Hintergrundbild in einem Canvas dargestellt und müssten per Touch und Mouse-Events gezoomt und geschoben werden können.
In der Anwendung ohne MVVM funktioniert das prima, nur habe ich jetzt Probleme bei der Umstellung.
Beim Manipulieren des Canvas per Touch "springen" die Inhalte hin und her, weil im Event "OnManipulationDelta" meist noch ein weiterer Aufruf auftrifft wo die Delta-Variablen das entgegengesetzte Vorzeichen haben.
Ich vermute hier einen grundlegenden Fehler meinerseits im Verständnis des Handlings und hoffe ihr könnt mir auf die Sprünge helfen.

XAML des views:


<UserControl x:Class="SC200_GUI.Views.RoomView"
             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:local="clr-namespace:SC200_GUI.ViewModels"
             xmlns:ctrl="clr-namespace:SC200_GUI.Controls"
             xmlns:res="clr-namespace:SC200_GUI.Resources"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <local:RoomViewModel/>
    </UserControl.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <!--<RowDefinition Name="rowMain" Height="1"/>-->
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Viewbox Grid.Row="2" x:Name="container">
            <Canvas x:Name="Room" IsManipulationEnabled="True" 
                    Background="Beige" Height="{Binding room.Height}" Width="{Binding room.Width}">
                <Image x:Name="Img1" Source="{Binding room.Img}"/>
                <ItemsControl ItemsSource="{Binding MyButtons}" Height="315" Width="770">
                    <ItemsControl.ItemsPanel >
                        <ItemsPanelTemplate>
                            <Canvas IsItemsHost="true"></Canvas>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button Margin="{Binding ControlMargin}" Content="{Binding Content}" Command="{Binding DataContext.ButtonCommand, 
                                RelativeSource={RelativeSource FindAncestor, 
                                AncestorType={x:Type UserControl}}}" CommandParameter="{Binding ProductId}"></Button>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Canvas>
        </Viewbox>
        <ListBox Grid.Row="0" ItemsSource="{Binding Log}"/>
    </Grid>
</UserControl>

Viewmodel:


namespace SC200_GUI.ViewModels
{
    public class RoomViewModel : ViewModelBase
    {
        private Room _room;
        private static double zoom = 1;
        private static Point MoveDelta = new Point(0, 0);
        public ObservableCollection<FluidButton> _myButtons;
        public Room room => _room;

        public ObservableCollection<FluidButton> MyButtons
        {
            get { return _myButtons; }
            set { _myButtons = value; }
        }
 #region UserEvents

        public ICommand ButtonCommand { get; }

        public ObservableCollection<string> Log { get; set; } = new ObservableCollection<string>();
        public void InsertLogEntry(string msg) => Log.Insert(0, msg);

        public static readonly DependencyProperty MouseEventsProperty =
          DependencyProperty.RegisterAttached("MouseEvents", typeof(bool),
                                              typeof(FrameworkElement),
                                              new UIPropertyMetadata(false, OnMouseEventsChanged));

        public static bool GetMouseEvents(DependencyObject obj) => (bool)obj.GetValue(MouseEventsProperty);
        public static void SetMouseEvents(DependencyObject obj, bool value) => obj.SetValue(MouseEventsProperty, value);

        private static void OnMouseEventsChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            var fwe = depObj as FrameworkElement;
            if (fwe == null || !(e.NewValue is Boolean)) return;
            if ((bool)(e.NewValue))
            {
                fwe.ManipulationStarting += OnManipulationStarting;
                fwe.ManipulationCompleted += OnManipulationCompleted;
                fwe.ManipulationDelta += OnManipulationDelta;
            }
            else
            {
                fwe.ManipulationStarting -= OnManipulationStarting;
                fwe.ManipulationCompleted -= OnManipulationCompleted;
                fwe.ManipulationDelta -= OnManipulationDelta;
            }
        }
       private static void OnManipulationStarting(object sender, ManipulationStartingEventArgs e)
        {
            var uie = sender as FrameworkElement;
            e.ManipulationContainer = uie;
            e.Mode = ManipulationModes.Translate;
            e.Handled = true;
        }
        private static void OnManipulationCompleted(object sender, EventArgs e)
        {
        }
        private static void OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            Canvas rectToMove = sender as Canvas;
            Matrix rectsMatrix = ((MatrixTransform)rectToMove.RenderTransform).Matrix;

            rectsMatrix.Translate(e.DeltaManipulation.Translation.X,
                                  e.DeltaManipulation.Translation.Y);
            rectToMove.RenderTransform = new MatrixTransform(rectsMatrix);
            Rect containingRect =
                new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);
            Rect shapeBounds =
                rectToMove.RenderTransform.TransformBounds(
                    new Rect(rectToMove.RenderSize));
            if (e.IsInertial && !containingRect.Contains(shapeBounds))
            {
                e.Complete();
            }
            e.Handled = true;
       }
        public RoomViewModel()
        {
            MyButtons = new ObservableCollection<FluidButton>();
            MyButtons.Add(new FluidButton("Test1", 0, 40, 1));
            MyButtons.Add(new FluidButton("Test2", 40, 80, 2));
            MyButtons.Add(new FluidButton("Test3", 80, 120, 3));
            MyButtons.Add(new FluidButton("Test4", 120, 160, 4));
            ButtonCommand = new ButtonCommand();
            changeRoomPic("milli.svg");
        }
}

Vielen Dank.