RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 687506
Accepted
Philippe
Philippe
Asked:2020-07-05 17:56:20 +0000 UTC2020-07-05 17:56:20 +0000 UTC 2020-07-05 17:56:20 +0000 UTC

在按钮中绘制椭圆

  • 772

我正在编写简单的井字游戏来测试Minimax 算法。这个想法是这样的:在 xaml 中,我创建了一个大小约为窗口 3/4 的常规 Canvas,在其中绘制 3 x 3 按钮,结果如下:

在此处输入图像描述

此外,我这样做:当点击按钮时,如果点击次数是偶数,我画一个十字,否则在按钮中间画一个圆圈。这是代码:

private void BoardButton_Click(object sender, RoutedEventArgs e)
{
    if (ClickCount > xDimension * yDimension) //3 * 3 = 9
        throw new Exception(); //Всего 9 клеток, если кликнули 9 раз - все клетки заполнены 

    Button _clicked = sender as Button;
    if (ClickCount % 2 == 0)
    {
        //Нарисовать крестик
    }
    else
    {
        Ellipse toDraw = CopyPlayer2Object; //Создает Ellipse со стандартными параметрами Width, Height, Stroke
        //Нужно нарисовать круг так, чтобы его центр был центром кнопки
        Canvas.SetLeft(toDraw, Canvas.GetLeft(_clicked) / 2);
        Canvas.SetTop(toDraw, Canvas.GetTop(_clicked) / 2); 

        CurrentLocation.Children.Add(toDraw); //Мой Canvas
    }

    ClickCount++;
}

不幸的是,圆圈并没有绘制在按钮的中间,而且根本没有绘制在按钮本身中。告诉我如何画一个圆

PS 我对 WPF 的经验很少,所以欢迎提供有关如何使井字游戏的创建更方便以及井字游戏本身更漂亮的提示!

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    VladD
    2020-07-05T19:38:10Z2020-07-05T19:38:10Z

    首先,让我们的领域成为正方形。简单的解决方案是写

    Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
    

    (稍后会有更好的解决方案)。

    现在,我们需要显示相同大小的单元格,为此它将执行UniformGrid:

    <UniformGrid Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
                 Rows="3" Columns="3">
        ...
    <UniformGrid/>
    

    现在,井字游戏本身。要绘制它们,最好将它们Path与合适的几何形状一起使用。由于几何将被重用,我们将其放入资源中。几何体将自由拉伸,所以让我们将其设为单一尺寸。

    对于零,这很简单:

    <EllipseGeometry x:Key="NoughtGeo" RadiusX="1" RadiusY="1"/>
    

    有了十字,就复杂一点了,我们来整理一下“乌龟图形”:

    <Geometry x:Key="CrossGeo">M 0,0 L 1,1 M 0,1 L 1,0</Geometry>
    

    现在,让我们画出我们的Button. 让我们缩进、拉伸几何图形并使线条更粗:

    <Button Padding="15">
        <Path Data="{StaticResource NoughtGeo}" Stroke="DarkGray"
              Stretch="Uniform" StrokeThickness="3"/>
    </Button>
    

    我们得到类似这样的代码:

    <Window x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:SO4WPF"
            Title="Тест" Height="350" Width="525">
        <Grid>
            <Grid.Resources>
                <Geometry x:Key="CrossGeo">M 0,0 L 1,1 M 0,1 L 1,0</Geometry>
                <EllipseGeometry x:Key="NoughtGeo" RadiusX="1" RadiusY="1"/>
            </Grid.Resources>
            <UniformGrid Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
                         Rows="3" Columns="3" Background="WhiteSmoke">
                <Button Padding="15" Margin="5">
                    <Path Data="{StaticResource NoughtGeo}" Stroke="DarkGray"
                          Stretch="Uniform" StrokeThickness="3"/>
                </Button>
                <Button Padding="15" Margin="5">
                    <Path Data="{StaticResource CrossGeo}" Stroke="DarkGray"
                          Stretch="Uniform" StrokeThickness="3"/>
                </Button>
            </UniformGrid>
        </Grid>
    </Window>
    

    结果:

    图片

    我们立即看到很多重复的代码需要扔进样式中。由于我们内部有控件,所以我们将它们放在ContentTemplate. 他自己Content要么是X,要么O。

    <Style TargetType="Button">
        <Setter Property="Padding" Value="15"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Path Stroke="DarkGray" Stretch="Uniform" StrokeThickness="3" Name="P"/>
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding}" Value="X">
                            <Setter TargetName="P" Property="Data"
                                    Value="{StaticResource CrossGeo}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding}" Value="O">
                            <Setter TargetName="P" Property="Data"
                                    Value="{StaticResource NoughtGeo}"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    现在按钮的样式很简单:

    <UniformGrid Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
                 Rows="3" Columns="3" Background="WhiteSmoke">
        <Button>X</Button>
        <Button>O</Button>
        <Button> </Button>
        <Button> </Button>
        <Button>X</Button>
        <Button> </Button>
        <Button>X</Button>
        <Button> </Button>
        <Button>O</Button>
    </UniformGrid>
    

    结果:

    再画一次


    现在关于方形字段的问题。为什么原来的解决方案不太好?让我们看看调整窗口大小时它的行为:

    哇,坏狗!

    在宽度太小的情况下,结果很难看。

    如何处理?没有代码它不会工作,但你可以AspectRatioDecorator 从这里使用帮助类:

    <local:AspectRatioDecorator>
        <UniformGrid Rows="3" Columns="3" Background="WhiteSmoke">
            <Button>X</Button>
            <Button>O</Button>
            <Button> </Button>
            <Button> </Button>
            <Button>X</Button>
            <Button> </Button>
            <Button>X</Button>
            <Button> </Button>
            <Button>O</Button>
        </UniformGrid>
    </local:AspectRatioDecorator>
    

    我们得到这个结果:

    马拉迪斯!


    我不喜欢上一张截图中的那个,当字段减少时,十字和零“崩溃”。他们的边界最好按比例减少。为此,我们将稍微更改几何形状,包括从边缘缩进 15%。

    对于十字,很简单,在开头添加“spacers”:

    <Geometry x:Key="CrossGeo">
        M 0,0 M 1,1 M 0.15,0.15 L 0.85,0.85 M 0.15,0.85 L 0.85,0.15
    </Geometry>
    

    对于零,您必须稍微修改一下。如果我们只是减小半径,什么都不会改变,因为我们仍然将它拉伸到按钮的整个宽度。因此,您必须放置一个单独的隐形垫片:

    <GeometryGroup x:Key="NoughtGeo">
        <EllipseGeometry RadiusX="0.85" RadiusY="0.85"/>
        <Geometry>M -1,-1 M 1,1</Geometry>
    </GeometryGroup>
    

    不要忘记Padding从样式中删除!

    我们得到:

    萨夫萨姆哈拉肖

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5