【问题标题】:Binding polygon points in XAML在 XAML 中绑定多边形点
【发布时间】:2014-07-16 00:13:30
【问题描述】:

有没有办法在 XAML 中绑定 Point 结构坐标?例如,我想创建一个三角形,它的点取决于控件的宽度和高度。

<Polygon>
   <Polygon.Points>
      <Point X="{Binding ElementName=control, Path=ActualWidth}" Y="{Binding ElementName=control, Path=ActualHeight}"/>
   </Polygon.Points>
</Polygon>

错误:

不能在“Point”类型的“X”属性上设置“绑定”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”。

我不能使用继承,因为 Point 类型是一个结构。我尝试创建 PointCollection 属性绑定,但效果不佳。

【问题讨论】:

  • 一个有 2 个点的三角形?
  • 不是,但这只是代码示例,会导致错误。但是,我声明了一点。
  • Converters 可以在这里为您提供帮助,您仍然可以绑定PolygonPoints 属性但是他们可能不会响应更改。
  • 我写道我试图绑定 Points 属性。你能发布一个正确绑定和转换点的例子吗?
  • 那么三角形应该如何适应控件的正方形边界?如果您可以发布图片来解释相同的内容,我们将不胜感激。

标签: c# wpf xaml binding


【解决方案1】:

给你

我尝试用两种方法解决三角形

结果


Viewbox 方法

如果您对呈现控件大小的三角形感兴趣,那么这可能是您的选择

<Grid>
    <Viewbox Stretch="Fill">
        <Path Data="M 1.5,0 L 3,3 0,3 Z" 
              Width="3" Height="3"
              Fill="Gray" />
    </Viewbox>
</Grid>

上述方法将渲染一个三角形并通过 Viewbox 调整到父控件的大小,此外,您可以为路径添加旋转变换并根据需要旋转三角形。

如果您无论如何都只需要一个三角形,建议使用此方法


使用转换器的多边形

<Grid xmlns:l="clr-namespace:CSharpWPF"
      x:Name="control">
    <Grid.Resources>
        <l:ElementToTrianglePointsConverter x:Key="ElementToTrianglePointsConverter" />
    </Grid.Resources>
    <Polygon Points="{Binding ElementName=control, Converter={StaticResource ElementToTrianglePointsConverter}}"
             FillRule="Nonzero"
             Fill="Gray" />
</Grid>

转换器

namespace CSharpWPF
{
    public class ElementToTrianglePointsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            FrameworkElement element = value as FrameworkElement;
            PointCollection points = new PointCollection();
            Action fillPoints = () =>
                {
                    points.Clear();
                    points.Add(new Point(element.ActualWidth / 2, 0));
                    points.Add(new Point(element.ActualWidth, element.ActualHeight));
                    points.Add(new Point(0, element.ActualHeight));
                };
            fillPoints();
            element.SizeChanged += (s, ee) => fillPoints();
            return points;// store;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

上面的方法有点麻烦,我总是必须重新调整窗口大小才能看到三角形。我可以在设计时默认看到它,但在运行时看不到它,除非我调整窗口大小。虽然多边形中有点但没有渲染,不知道为什么?需要调查问题

【讨论】:

  • 我不知道该如何解决。
  • 我也没有。顺便说一句,您如何看待 Viewbox 方法?这符合您的需求吗?
【解决方案2】:

你可以使用MultiBinding和转换器。

可能看起来像这样:

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local ="clr-namespace:WpfApplication13"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:converter x:Key="pointConverter" />
    </Window.Resources>
    <Grid x:Name="control" >
        <Polygon Fill="Black" Stroke="Black">
            <Polygon.Points>
                <MultiBinding  Converter="{StaticResource pointConverter}" >
                    <Binding Path="ActualWidth"  ElementName="control"/>
                    <Binding Path="ActualHeight"  ElementName="control"/>
                </MultiBinding>
            </Polygon.Points>
        </Polygon>
    </Grid>
</Window>

或者您可以在后台进行:

public MainWindow()
        {
            InitializeComponent();
            MultiBinding mb = new MultiBinding();

            Binding bind = new Binding("ActualWidth");
            bind.Source = control;

            mb.Bindings.Add(bind);

            bind = new Binding("ActualHeight");
            bind.Source = control;

            mb.Bindings.Add(bind);
            mb.Converter = new converter();

            pg.SetBinding(Polygon.PointsProperty, mb);
        }




class converter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                double width = (double)values[0];
                double height = (double)values[1];

                PointCollection pc = new PointCollection();
                pc.Add(new Point(0, 0));
                pc.Add(new Point(width - 10, height - 10));
                return pc;
            }
            catch
            {
                return null;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

【讨论】:

  • 您不能对 PointCollection 使用多重绑定。
  • @vdrake6 为什么?不绑定PointCollection,是Points,是dependencyproperty。
  • 错误 1 ​​无法将“MultiBinding”类型的实例添加到“PointCollection”类型的集合中。只允许使用“Point”类型的项目。
  • @vdrake6 这是XAML中vs2012/13的一个bug,运行时没问题
【解决方案3】:

我刚刚解决了我的问题。我使用@pushpraj 解决方案的想法,但我将 ActualWidth 和 ActualHeight 更改为 Width 和 Height 所以我的转换器类现在看起来像这样:

namespace CSharpWPF
{
public class ElementToTrianglePointsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        FrameworkElement element = value as FrameworkElement;
        PointCollection points = new PointCollection();
        Action fillPoints = () =>
            {
                points.Clear();
                points.Add(new Point(element.Width / 2, 0));
                points.Add(new Point(element.Width, element.Height));
                points.Add(new Point(0, element.Height));
            };
        fillPoints();
        element.SizeChanged += (s, ee) => fillPoints();
        return points;// store;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
}

我认为 ActualWidth 和 ActualHeight 属性是在初始化所有子控件时初始化的。

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 2014-11-18
    • 2014-04-11
    • 2012-01-14
    相关资源
    最近更新 更多