C#WPF获取不正确的转换绑定信息?

时间:2017-08-31 05:33:02

标签: c# wpf xaml transform bounds

我创建了一个平铺匹配游戏,玩家将平铺拖动到平铺支架上,如果放置了正确的平铺,则获得积分。请参阅下图以供参考:

tile match game

我正在使用ScatterView控件,从Microsoft.Surface.Presentation作为一个板来保存我的tile,以及ScatterViewItems,作为tile本身。

我希望能够将ScatterViewItems放到持有者身上,并为相应的持有者评估它是否可以接受放在它上面的瓷砖。

我已经设法获得了我需要的大量信息,但是我从我的瓷砖持有者那里获得的变换界限信息是否有偏差?

我正在使用touch up事件,而rect包含/ intersectswith方法,但是我得到的关于tile holder的结果不正确。虽然许多结果很接近,但它们都略有不同。我试过画我的作品'到画布,但它显示正确的点和尺寸。

我最初正在旋转我的一些控件,因为我需要它们沿着电路板的侧面,然而停止了这一点,因为它被认为是责备,但结果仍然是错误的。您会注意到(如果您获得解决方案zip),在某些持有者上,边界将无法正确注册,而有时当没有超过持有者(就在附近)时它会。我认为我使用的矩形界限不正确,但我看不出错误!真的很感激任何帮助。

这是指向解决方案拉链的链接(VS2015):project solution as zip

如果您愿意,可以使用主要代码:

using Microsoft.Surface.Presentation.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TestingSVI_Intersection
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static Action EmptyDelegate = delegate () { };
        StackPanel[] stacks = new StackPanel[4];
        Vector tileSize = new Vector(60, 80);
        Vector holderSize = new Vector(0, 0);
        Vector gameGridSize = new Vector(0, 0);
        int numberOfLetters = 5;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Svi_PreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            ScatterViewItem svi = e.Source as ScatterViewItem;
            Point p1 = svi.TransformToAncestor(MiddleGrid).Transform(new Point(0, 0));

            Rect r1 = new Rect(p1.X, p1.Y, svi.ActualWidth, svi.ActualHeight);
            Console.WriteLine($"SVI at: {svi.ActualCenter}");

            Rectangle rectangle;

            foreach (StackPanel panel in stacks)
            {
                foreach (UserControl holder in panel.Children)
                {

                    Point p2 = holder.TransformToAncestor(MiddleGrid).Transform(new Point(0, 0));

                    Rect r2 = new Rect(p2.X, p2.Y, holder.ActualWidth, holder.ActualHeight);
                    rectangle = new Rectangle();
                    rectangle.Width = holder.Width;
                    rectangle.Height = holder.Height;
                    Canvas.SetLeft(rectangle, p2.X);
                    Canvas.SetTop(rectangle, p2.Y);
                    rectangle.Stroke = new SolidColorBrush(Colors.SpringGreen);
                    rectangle.StrokeThickness = 1;
                    canvasMe.Children.Add(rectangle);

                    if (r2.IntersectsWith(r1) == true)
                    {
                        if (r2.Contains(p1))
                        {
                            Console.WriteLine($"Intersection at: {holder.Name}");
                        }

                    }
                }
            }
        }

        private void IntersectionFound(ScatterViewItem svi, UserControl uC)
        {

        }

        //private void Svi_PreviewTouchUp(object sender, TouchEventArgs e)
        //{
        //    ScatterViewItem svi = e.Source as ScatterViewItem;
        //    Point p1 = svi.TransformToAncestor(mainGrid).Transform(new Point(0, 0));

        //    Rect r1 = new Rect(p1.X, p1.Y, svi.ActualWidth, svi.ActualHeight);
        //    Console.WriteLine($"SVI at: {svi.ActualCenter}");
        //    foreach (StackPanel panel in stacks)
        //    {
        //        foreach (UserControl holder in panel.Children)
        //        {

        //            Point p2 = holder.TransformToAncestor(mainGrid).Transform(new Point(0, 0));

        //            Rect r2 = new Rect(p2.X, p2.Y, holder.ActualWidth, holder.ActualHeight);

        //            Console.WriteLine($"Checked: {holder.Name} at centre: ({p2.X + holder.Width / 2}, {p2.Y + holder.Height / 2})");

        //            //if (r1.IntersectsWith(r2) == true)
        //            //{

        //            //    Console.WriteLine($"Intersection at: {holder.Name}");
        //            //}
        //            if (r2.Contains(r1) == true)
        //            {
        //                Console.WriteLine($"Intersection at: {holder.Name}");
        //            }
        //        }
        //    }
        //}

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (stacks[3] != null)
            {
                foreach (StackPanel panel in stacks)
                {
                    panel.Children.Clear();
                }

                canvasMe.Children.Clear();
                scatterView.Items.Clear();
            }
            gameGridSize.X = MiddleGrid.ActualWidth;
            gameGridSize.Y = MiddleGrid.ActualHeight;

            holderSize.X = gameGridSize.X * 0.10f;
            holderSize.Y = gameGridSize.Y * 0.15f;

            stacks[0] = letterHolders1;
            stacks[1] = letterHolders2;
            stacks[2] = letterHolders3;
            stacks[3] = letterHolders4;

            int count = 0;
            foreach (StackPanel panel in stacks)
            {
                for (int i = 0; i < numberOfLetters; i++)
                {
                    UserControl uC = new UserControl
                    {
                        Width = holderSize.X,
                        Height = holderSize.Y,
                        Background = new SolidColorBrush(Colors.Black),
                        BorderThickness = new Thickness(1),
                        BorderBrush = new SolidColorBrush(Colors.Yellow),
                        Name = $"UC_{count.ToString()}"
                    };

                    count++;

                    if (panel == stacks[1] || panel == stacks[2])
                    {
                        //uC.LayoutTransform = new RotateTransform(90);
                        uC.Width = holderSize.Y;
                        uC.Height = holderSize.X;
                    }
                    panel.Children.Add(uC);
                }
            }

            MiddleGrid.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);

            Console.WriteLine($"Stack 2: ({letterHolders2.ActualWidth}, {letterHolders2.ActualHeight})");

            holderSize.X = letterHolders2.ActualHeight / numberOfLetters;

            tileSize.X = holderSize.X * 0.8f;
            tileSize.Y = holderSize.Y * 0.8f;

            foreach (StackPanel panel in stacks)
            {
                foreach (UserControl control in panel.Children)
                {
                    control.Width = holderSize.X;
                    control.Height = holderSize.Y;

                    if (panel == stacks[1] || panel == stacks[2])
                    {
                        control.Width = holderSize.Y;
                        control.Height = holderSize.X;
                    }
                }
            }

            for (int i = 0; i < 10; i++)
            {
                ScatterViewItem svi = new ScatterViewItem
                {
                    Width = tileSize.X,
                    MinWidth = tileSize.X,
                    MaxWidth = tileSize.X,
                    Height = tileSize.Y,
                    MinHeight = tileSize.Y,
                    MaxHeight = tileSize.Y,
                    Background = new SolidColorBrush(Colors.Red),

                };

                //svi.PreviewTouchUp += Svi_PreviewTouchUp;
                svi.PreviewMouseUp += Svi_PreviewMouseUp;

                scatterView.Items.Add(svi);
            }

        }
    }
}

它对应的XAML:

<Window x:Class="TestingSVI_Intersection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:s="http://schemas.microsoft.com/surface/2008"
        xmlns:local="clr-namespace:TestingSVI_Intersection"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Grid x:Name="mainGrid">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition  Width="70"/>
                <ColumnDefinition  Width="*"/>
                <ColumnDefinition  Width="70"/>
            </Grid.ColumnDefinitions>

            <Grid Background="Black" Grid.Column="0">
                <Grid.RowDefinitions>
                    <RowDefinition  Height="64"/>
                    <RowDefinition/>
                    <RowDefinition  Height="64"/>
                </Grid.RowDefinitions>

                <Grid Grid.Row="0" Background="Gray"/>
                <Grid Grid.Row="1"/>
                <Grid Grid.Row="2" Background="Gray"/>
            </Grid>

            <Grid Background="Black" Grid.Column="2">
                <Grid.RowDefinitions>
                    <RowDefinition  Height="64"/>
                    <RowDefinition/>
                    <RowDefinition  Height="64"/>
                </Grid.RowDefinitions>

                <Grid Grid.Row="0" Background="Gray"/>
                <Grid Grid.Row="1">
                    <Button x:Name="startButton" Content="Start" Height="60" VerticalAlignment="Top" Background="Blue" Foreground="White" Click="Button_Click"/>
                </Grid>
                <Grid Grid.Row="2" Background="Gray"/>
            </Grid>

            <Grid Grid.Column="1" Grid.Row="1" x:Name="MiddleGrid">
                <Grid x:Name="GameGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.2*"/>
                        <ColumnDefinition Width="0.6*"/>
                        <ColumnDefinition Width="0.2*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="0.2*"/>
                        <RowDefinition Height="0.6*"/>
                        <RowDefinition Height="0.2*"/>
                    </Grid.RowDefinitions>

                    <StackPanel x:Name="letterHolders1" Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top">

                    </StackPanel>

                    <StackPanel x:Name="letterHolders2" Orientation="Vertical" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center">

                    </StackPanel>

                    <StackPanel x:Name="letterHolders3" Orientation="Vertical" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center">

                    </StackPanel>

                    <StackPanel x:Name="letterHolders4" Orientation="Horizontal" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Bottom">

                    </StackPanel>


                </Grid>
                <s:ScatterView x:Name="scatterView">

                </s:ScatterView>

                <Canvas x:Name="canvasMe" IsHitTestVisible="False"/>
            </Grid>
        </Grid>
    </Grid>
</Window>

0 个答案:

没有答案