WP7 - 拖放从 Canvas 内的 DataTemplate 创建的对象
概览:
我的应用程序显示一个 ItemsControl,其中包含 Canvas 作为其 ItemsPanel。 ItemsControl 绑定到对象集合,每个对象都具有 Left/Top/Width/Height 属性。 DataTemplate 用于生成在 Canvas 中呈现并正确定位的矩形(绑定在 Left 和 Top 属性上)。
如何实现拖放来在画布上移动这些矩形?
我的问题背景:
我的 WP7 应用程序显示一个“CanvasItemsControl”,定义如下:
public class CanvasItemsControl : ItemsControl
{
public string XBindingPath { get; set; }
public string YBindingPath { get; set; }
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
FrameworkElement contentitem = element as FrameworkElement;
if (XBindingPath != null && YBindingPath != null)
{
Binding xBinding = new Binding(XBindingPath);
Binding yBinding = new Binding(YBindingPath);
if (contentitem != null)
{
contentitem.SetBinding(Canvas.LeftProperty, xBinding);
contentitem.SetBinding(Canvas.TopProperty, yBinding);
}
}
base.PrepareContainerForItemOverride(element, item);
}
}
并在 XAML 中使用如下:
<hh:CanvasItemsControl Grid.Row="1" x:Name="TheItemsControl"
Style="{StaticResource CanvasItemsControlStyle}"
ItemsSource="{Binding AllObjects}"
XBindingPath="Left" YBindingPath="Top" />
这是 CanvasItemsControl 的样式: 这
<Style x:Key="CanvasItemsControlStyle" TargetType="local:CanvasItemsControl">
<Setter Property="ItemTemplate" Value="{StaticResource ObjectTemplate}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
是我用来呈现类的 DataTemplate:
<DataTemplate x:Key="ObjectTemplate" >
<Border Background="{Binding Brush}"
Width="{Binding Width}"
Height="{Binding Height}">
<TextBlock Text="{Binding Description}"/>
</Border>
</DataTemplate>
CanvasItemsControl 的源是对象的集合,具有左侧、顶部、宽度、高度、画笔等属性。
我的问题
正如您所看到的,最终结果是,当您将项目添加到 AllObjects 集合时,每个对象都会在画布中正确渲染和定位。现在我需要在画布上拖/放/移动这些对象。您建议我使用什么方法来实现拖/放?您能指导我完成整个过程吗?
谢谢
At a glance:
My app displays an ItemsControl containing a Canvas as its ItemsPanel. The ItemsControl is bound to a collection of objects, each having Left/Top/Width/Height properties. A DataTemplate is used to generate rectangles that are rendered in the Canvas and positioned correctly (binding on the Left and Top properties).
How can I implement drag/drop to move these rectangles around the Canvas?
Background for my question:
My WP7 app displays a "CanvasItemsControl" defined as follows:
public class CanvasItemsControl : ItemsControl
{
public string XBindingPath { get; set; }
public string YBindingPath { get; set; }
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
FrameworkElement contentitem = element as FrameworkElement;
if (XBindingPath != null && YBindingPath != null)
{
Binding xBinding = new Binding(XBindingPath);
Binding yBinding = new Binding(YBindingPath);
if (contentitem != null)
{
contentitem.SetBinding(Canvas.LeftProperty, xBinding);
contentitem.SetBinding(Canvas.TopProperty, yBinding);
}
}
base.PrepareContainerForItemOverride(element, item);
}
}
and used in XAML as follows:
<hh:CanvasItemsControl Grid.Row="1" x:Name="TheItemsControl"
Style="{StaticResource CanvasItemsControlStyle}"
ItemsSource="{Binding AllObjects}"
XBindingPath="Left" YBindingPath="Top" />
This is the style for the CanvasItemsControl:
<Style x:Key="CanvasItemsControlStyle" TargetType="local:CanvasItemsControl">
<Setter Property="ItemTemplate" Value="{StaticResource ObjectTemplate}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
And this is the DataTemplate I use to render my class:
<DataTemplate x:Key="ObjectTemplate" >
<Border Background="{Binding Brush}"
Width="{Binding Width}"
Height="{Binding Height}">
<TextBlock Text="{Binding Description}"/>
</Border>
</DataTemplate>
The source of the CanvasItemsControl is a collection of objects that have the properties Left, Top, Width, Height, Brush, etc.
My question
As you can see, the end result is, as you add items to the AllObjects collection, each object gets rendered and positioned correctly in the canvas. Now I need to drag/drop/move these objects around the canvas. What approach would you advise me to use to implement drag/drop? Can you please guide me through the process?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我的问题的解决方案(至少在我看来是最好的解决方案):
1)使用常规 Canvas,而不是从 Canvas 继承的自定义控件。
2)使用用户控件通过构造函数获取数据上下文(我的业务实体的实例)
3) 我的业务类的 Left/Top 属性和 Canvas.Left/Top 之间的绑定是在 UserControl 级别声明的。
4) 使用继承自System.Windows.Interactivity.Behavior的自定义行为。此行为附加到用户控件。
我要感谢 Calvin Schrotenboer 和 Joe Gershgorin 的巨大贡献帮助。
自定义行为:
Here's the solution to my question (at least the best one in my opinion):
1) Use of a regular Canvas as opposed of a custom control inherited from Canvas.
2) Use of a user control taking the data context (the instance of my business entity) via constructor
3) The binding between the Left/Top properties of my business class and the Canvas.Left/Top is declared at the UserControl level.
4) Use of a custom behavior inheriting from System.Windows.Interactivity.Behavior. This behavior is attached to the User Control.
I would like to acknowlege Calvin Schrotenboer and Joe Gershgorin for their immense help.
The custom behavior: