用作ItemsControl ItemsPanel时绑定画布X,Y

时间:2012-08-27 11:10:58

标签: windows-phone-7 canvas

我有一个画布,我很想在指定的XY位置绑定一些点。但是,我无法用ItemsControl实现这一点。我找到了一些解决方案,但我想它们不适用于Windows Phone。

我正在使用的XAML是:

<ItemsControl ItemsSource="{Binding Path=Nodes}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

我得到:“成员”ItemContainerStyle“无法识别或无法访问”

如何以其他方式进行这种绑定?我有对象的名称,而我想要绑定的X / Y值是某种图钉

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题但是使用TriggerAction解决了它。如果您拥有Blend SDK,则可以使用System.Windows.Interactivity。该DLL位于

c:\Program Files\Microsoft SDKs\Expression\Blend\Silverlight\v4.0\Libraries\
System.Windows.Interactivity.dll`

然后,通过使用您之前的xaml代码,我可以设置datatemplate:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Ellipse Stroke="Red" Width="2" Height="2">
            <ia:Interaction.Triggers>
                <ia:EventTrigger EventName="Loaded">
                    <tr:SetCanvasPropertiesAction Left="{Binding X}" Top="{Binding Y}" />
                </ia:EventTrigger>
            </ia:Interaction.Triggers>
        </Ellipse>
    </DataTemplate>
</ItemsControl.ItemTemplate>

请注意前面提到的交互dll中的ia:Interaction前缀。你用

加载它
xmlns:ia="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

位于xaml文件的顶部。

tr前缀用于包含我自己的类,如下所示:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace Presentation.Triggers {
    public class SetCanvasPropertiesAction : TriggerAction<DependencyObject> {
        public static readonly DependencyProperty LeftProperty =
            DependencyProperty.Register("Left", typeof(double), typeof(SetCanvasPropertiesAction), new PropertyMetadata(default(double)));

        public static readonly DependencyProperty TopProperty =
            DependencyProperty.Register("Top", typeof(double), typeof(SetCanvasPropertiesAction), new PropertyMetadata(default(double)));

        public double Top {
            get { return (double)GetValue(TopProperty); }
            set { SetValue(TopProperty, value); }
        }

        public double Left {
            get { return (double)GetValue(LeftProperty); }
            set { SetValue(LeftProperty, value); }
        }

        protected override void Invoke(object parameter) {
            UIElement presenter = (UIElement)VisualTreeHelper.GetParent(AssociatedObject);
            Canvas.SetLeft(presenter, Left);
            Canvas.SetTop(presenter, Top);
        }
    }
}

Invoke方法需要注意两点。第一个是AssociatedObject,它被解析为Ellipse,因为触发器嵌套在xaml中。第二件事是VisualTreeHelper,它获取椭圆的父级。这是我们要在其上设置画布的附加属性的ContentPresenter。

它可能看起来更复杂,但与mvvm中的其​​他内容一样,您可以在xaml中重用它,而不必在任何地方复制和粘贴代码隐藏代码。

答案 1 :(得分:0)

最后我只使用foreach在C#中完成。

foreach (var InsidePoints in _inside)
            {
                double left = InsidePoints.xaxis * Layer_3.Width;
                double top = InsidePoints.yaxis * Layer_3.Height;
                Image pinImage = new Image();
                pinImage.Name = InsidePoints.id.ToString();
                pinImage.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("icons/inside_pin.png");
                pinImage.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(pinImage_Tap);
                //pinImage.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(pinImage_Hold);
                Layer_3.Children.Add(pinImage);
                Canvas.SetLeft(pinImage, left);
                Canvas.SetTop(pinImage, top);
            }