【问题标题】:Silverlight: How to move items in ItemsControl in CanvasSilverlight:如何在 Canvas 的 ItemsControl 中移动项目
【发布时间】:2023-03-23 13:30:01
【问题描述】:

我有一个 ItemsControl,它将 UserControl 显示为 ItemTemplate。它有一个 Canvas ItemsPanel。

   <ItemsControl ItemsSource="{Binding Path=MyItems}" Margin="200,20,0,0">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:MyControl Margin="10,10,10,10"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Height="2000" Width="2000"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

我想在鼠标拖动时将控件移动到画布上

MyControl 有一个行为:

<UserControl x:Class="MyControl">

    <StackPanel x:Name="LayoutRoot" >
        <Grid Background="LightBlue" Height="20">
    </StackPanel>
<Interactivity:Interaction.Behaviors>
    <Behavior:DragControlBehavior />
</Interactivity:Interaction.Behaviors>
</UserControl>

DragControlBehavior 将鼠标移动上的 Canvas 附加属性设置在控件上

[更新] - 这是 Behavior 的完整源代码

public class DragControlBehavior : Behavior<MyControl>
{
    private DependencyObject _parent;
    private bool _isMouseCaptured = false;

    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += (sender, e) =>
        {
            _isMouseCaptured = true;
        };

        AssociatedObject.MouseLeftButtonUp += (sender, e) =>
        {
            _isMouseCaptured = false;
        };

        AssociatedObject.MouseMove += (sender, e) =>
        {
            if (_isMouseCaptured)
            {
                if (_parent == null)
                {
                    _parent = VisualTreeHelper.GetParent(AssociatedObject);
                    while (_parent.GetType() != typeof(Canvas))
                        _parent = VisualTreeHelper.GetParent(_parent);
                }
                var pointOnCanvas = e.GetPosition((Canvas)_parent);
                Canvas.SetTop(AssociatedObject, pointOnCanvas.Y);
                Canvas.SetLeft(AssociatedObject, pointOnCanvas.X);
            }
        };
    }

如果我在 Canvas 上单独使用 MyControl 的实例,它可以工作,但如果 ItemsControl 中有 MyControl 的集合,它们不会在 MouseMove 上移动

在 WPF 中,我会使用 ItemContainerStyle,但在 SL 中它不可用:

        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding Left}"/>
                <Setter Property="Canvas.Top" Value="{Binding Top}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>

【问题讨论】:

  • 你能告诉我们你的DragControlBehavior类的完整源代码吗?否则,我们很难重现您的问题。
  • 附加行为的完整源代码

标签: silverlight silverlight-4.0 canvas itemscontrol


【解决方案1】:

当您使用ItemsControl 时,生成的每个项目都包含在ContentPresenter 中。可视化树如下所示:

System.Windows.Controls.ItemsControl System.Windows.Controls.ItemsPresenter System.Windows.Controls.Canvas System.Windows.Controls.ContentPresenter DragControlBehaviorTest.MyControl ...

DragControlBehaviorTest 是我为试用您的代码而创建的项目的名称。)

Canvas.LeftCanvas.Top 附加属性仅适用于 Canvas 的直接子级。如果您将MyControl 直接放在Canvas 中,那么您的MyControlCanvas 的子代,因此在其上设置Canvas.LeftCanvas.Top 将起作用。但是,如果您使用ItemsControl 生成MyControls,则Canvas 和每个MyControls 之间都有一个ContentPresenter。您需要在这些 ContentPresenters 上设置 Canvas.LeftCanvas.Top 属性。

您有一个循环,该循环从 AssociatedObject 向上运行,以查找祖先 Canvas。您可以修改它以找到画布的直接子级,使用如下内容:

            _immediateChild = AssociatedObject;
            _parent = VisualTreeHelper.GetParent(AssociatedObject);
            while (_parent.GetType() != typeof(Canvas))
            {
                _immediateChild = _parent;
                _parent = VisualTreeHelper.GetParent(_parent);
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多