简体   繁体   中英

Adapting a Win8 store app tutorial to WPF

I'm following this tutorial that explains how to create a Dial in Visual Studio with XAML/C#. The problem is that the tutorial is targeted for windows 8 store apps.

Knowing that, I still tried to use this tutorial in a WPF application that will support previous OSs too.

I came across a few compatibility problems:

  1. ManipulationMode="All" doesn't exists as the author of the tutorial uses it for me. It only exists as Manipulation.ManipulationMode="All" which gives me an error "Manipulation is not active on the specified element". How could I solve it?
  2. The author set the ManipulationDelta property on the grid element, which I didn't have problem with at first... Until I realized the author's event/action code-behind created by VS uses ManipulationDeltaRoutedEventArgs e instead of the ManipulationDeltaEventArgs e which is used in my code-behind file. This means I can't use the Position property ( e.Position ) to get the mouse position on the user control as easily. What could be an alternative to it? I don't think it could be supported as it was declared as Win8 only...
  3. In an MVVM-style application, the code-behind actions would have been set in the ViewModel . How would I 'bind' that action code to the ManipulationDelta property of an element?

Thanks in advance!

PS; Both mine and the author's version of VS is 2012 so that's not the problem.

UPDATE: Here's the partially-completed code:

The XAML:

//Manipulation.ManipulationMode="All" => ERROR 'Manipulation is not active on the specified element'
<Grid Manipulation.ManipulationMode="All" ManipulationDelta="Grid_ManipulationDelta_1">
    <Ellipse Fill="#FF7171E6" Margin="30"/>
    <Grid>
        <Grid.RenderTransform>
            <RotateTransform CenterX="225" CenterY="225" Angle="{Binding Angle}"/>
        </Grid.RenderTransform>
        <Ellipse Fill="White" Height="100" VerticalAlignment="Top" Margin="50" Width="100"/>

    </Grid>
</Grid>

The code-behind:

public partial class dial : UserControl, INotifyPropertyChanged
{
    private int m_Amount;
    public int Amount {...}

    private double m_Angle;
    public double Angle {...}

    public dial()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void Grid_ManipulationDelta_1(object sender, ManipulationDeltaEventArgs e)
    {
        this.Angle = GetAngle(e.Position, this.RenderSize); //e.Position doesn't exist in ManipulationDeltaEventArgs...
        this.Amount = (int)(this.Angle / 360 * 100);
    }

    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;
    }

    public event PropertyChangedEventHandler PropertyChanged;

}
  1. In WPF, you can use IsManipulationEnabled="true" to enable manipulation. Don't need to use ManipulationMode="All" like Windows store app.
  2. You can try Mouse.GetPosition(this) to get current mouse position

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM