Home > OS >  WPF volume dial code tutorial code has issues in my code but none in the tutorial code
WPF volume dial code tutorial code has issues in my code but none in the tutorial code

Time:09-16

Hey all I need some help with getting the code below working. I was following enter image description here

UPDATE #2 The code should produce a dial:

enter image description here

UPDATE #3: Let mouse act as touch device

Adding the MouseTouchDevice.cs class in BlakeNUI:

public class MouseTouchDevice : TouchDevice, ITouchDevice
{
//Class Members

private static MouseTouchDevice device;

public Point Position { get; set; }

//Public Static Methods

public static void RegisterEvents(FrameworkElement root)
{
    root.PreviewMouseDown  = MouseDown;
    root.PreviewMouseMove  = MouseMove;
    root.PreviewMouseUp  = MouseUp;
    root.LostMouseCapture  = LostMouseCapture;
    root.MouseLeave  = MouseLeave;
}

//Private Static Methods

private static void MouseDown(object sender, MouseButtonEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.ReportUp();
        device.Deactivate();
        device = null;
    }
    device = new MouseTouchDevice(e.MouseDevice.GetHashCode());
    device.SetActiveSource(e.MouseDevice.ActiveSource);
    device.Position = e.GetPosition(null);
    device.Activate();
    device.ReportDown();
}

private static void MouseMove(object sender, MouseEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.Position = e.GetPosition(null);
        device.ReportMove();
    }
}

private static void MouseUp(object sender, MouseButtonEventArgs e)
{
    LostMouseCapture(sender, e);
}

static void LostMouseCapture(object sender, MouseEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.Position = e.GetPosition(null);
        device.ReportUp();
        device.Deactivate();
        device = null;
    }
}

static void MouseLeave(object sender, MouseEventArgs e)
{
    LostMouseCapture(sender, e);
}

//Constructors

public MouseTouchDevice(int deviceId) :
    base(deviceId)
{
    Position = new Point();
}

//Overridden methods

public override TouchPointCollection GetIntermediateTouchPoints(IInputElement relativeTo)
{
    return new TouchPointCollection();
}

public override TouchPoint GetTouchPoint(IInputElement relativeTo)
{
    Point point = Position;
}

to my project and placing this:

public watchingMovie(String movie)
{
    InitializeComponent();
    MouseTouchDevice.RegisterEvents(this);
    ...
}

Allows it to function as if you were working with it on a touch device.

CodePudding user response:

Try to replace e.Position with e.ManipulationOrigin in the event handler and set the IsManipulationEnabled property of the Grid to true in the XAML markup:

<Grid  IsManipulationEnabled="True" ...

You also need to actually implement the SetProperty<T> method.

CodePudding user response:

Currently the issues are:

Error CS1061 'ManipulationDeltaEventArgs' does not contain a definition for 'Position' and no accessible extension method 'Position' accepting a first argument of type 'ManipulationDeltaEventArgs' could be found (are you missing a using directive or an assembly reference?)

This error is because it doesn't exist, you can replace .Position with ManipulationOrigin which gets the point from which the manipulation originated and returns a System.Windows.Point:

 this.Angle = GetAngle(e.ManipulationOrigin, this.RenderSize);
 

Error CS7036 There is no argument given that corresponds to the required formal parameter '' of 'dial.SetProperty(ref T, T, ?)'

Please see example implementation below:

 public event PropertyChangedEventHandler PropertyChanged;
 protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propName = "")
 {
    if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
    storage = value;
    OnPropertyChanged(propName);
    return true;
 }

Error Manipulation is not active on the specified element.

To fix this issue set IsManipulationEnabled="True" on the grid iteself which means manipulation is enabled for the UIElement

All of this wrapped up:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace carProg
{
    /// <summary>
    /// Interaction logic for dial.xaml
    /// </summary>
    public partial class dial : UserControl, INotifyPropertyChanged
    {
        public dial()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        private void Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            this.Angle = GetAngle(e.ManipulationOrigin, this.RenderSize);
            this.Amount = (int)(this.Angle / 360 * 100);
        }

        int m_Amount = default(int);
        public int Amount
        {
            get { return m_Amount; }
            set
            {
                SetProperty(ref m_Amount, value);
            }
        }

        double m_Angle = default(double);
        public double Angle
        {
            get { return m_Angle; }
            set
            {
                SetProperty(ref m_Angle, value);
            }
        }

        // Please note the changes with OnPropertyChanged and SetProperty
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propName = "")
        {
            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
            storage = value;
            OnPropertyChanged(propName);
            return true;
        }

        public enum Quadrants : int { nw = 2, ne = 1, sw = 4, se = 3 }
        private double GetAngle(Point touchPoint, Size circleSize)
        {
            var _X = touchPoint.X - (circleSize.Width / 2d);
            var _Y = circleSize.Height - touchPoint.Y - (circleSize.Height / 2d);
            var _Hypot = Math.Sqrt(_X * _X   _Y * _Y);
            var _Value = Math.Asin(_Y / _Hypot) * 180 / Math.PI;
            var _Quadrant = (_X >= 0) ?
                (_Y >= 0) ? Quadrants.ne : Quadrants.se :
                (_Y >= 0) ? Quadrants.nw : Quadrants.sw;
            switch (_Quadrant)
            {
                case Quadrants.ne: _Value = 090 - _Value; break;
                case Quadrants.nw: _Value = 270   _Value; break;
                case Quadrants.se: _Value = 090 - _Value; break;
                case Quadrants.sw: _Value = 270   _Value; break;
            }
            return _Value;
        }
    }
}

// Please note: IsManipulationEnabled on the grid
<Grid IsManipulationEnabled="True" ManipulationDelta="Grid_ManipulationDelta">
        <Ellipse Margin="30"
                 Fill="#FFFFE15D"
                 Stroke="Black"
                 />
        <Grid>
            <Grid.RenderTransform>
                <RotateTransform Angle="{Binding Angle}" CenterX="225" CenterY="225" />
            </Grid.RenderTransform>
            <Ellipse Width="100"
                     Height="100"
                     Margin="0"
                     VerticalAlignment="Top"
                     Fill="#FFFFFDF3"
                     Stroke="Black"
                     />
        </Grid>
    </Grid>
  • Related