DataTemplate中的MouseDragElementBehavior

时间:2013-12-18 12:59:00

标签: wpf datatemplate

所以这是我遇到的一个问题。我正在尝试在列表框中使用MouseDragElementBehavior。当我直接在列表框中创建项目时,我能够使它工作,如下例所示:

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.Items>
            <Border Width="20" Height="20">

                    <i:Interaction.Behaviors>
                        <ei:MouseDragElementBehavior ConstrainToParentBounds="True"/>
                    </i:Interaction.Behaviors>

                    <Rectangle Fill="Red"/>

                </Border>
        </ItemsControl.Items>

    </ItemsControl>

但是一旦我开始使用DataTemplate,它就会停止工作。

    <ItemsControl Grid.Column="1" >

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.Items>
            Test item
        </ItemsControl.Items>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border Width="20" Height="20">

                    <i:Interaction.Behaviors>
                        <ei:MouseDragElementBehavior ConstrainToParentBounds="True"/>
                    </i:Interaction.Behaviors>

                    <Rectangle Fill="Red"/>

                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

    </ItemsControl>

为什么有任何想法?我无法弄清楚DataTemplate将如何影响MouseDragElementBehavior。

1 个答案:

答案 0 :(得分:0)

MouseDragElementBehavior对您附加到的FrameworkElement起作用。在您的情况下,Border元素将包含在ContentPresenter中,ItemsControlConstrainToParentBounds="True"生成的容器。您已设置ContentPresenter,以确保视觉效果不会在其容器(在本例中为ConstrainToParentBounds="False")之外显示。有几种选择,一些简单,一种可能不值得承担(但我确实想出了一些办法)。

  1. 设置Border。我假设您不希望ItemsControl离开ItemContainerStyle,所以这可能不合适。
  2. Style设置为Template,将ContentPresenter设置为ItemsControl并将交互添加到类似配置的ContentPresenter <ItemsControl Grid.Column="1" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <ContentPresenter> <i:Interaction.Behaviors> <ei:MouseDragElementBehavior ConstrainToParentBounds="True"/> </i:Interaction.Behaviors> </ContentPresenter> </ControlTemplate> </Setter.Value> </Setter> </Style > </ItemsControl.ItemContainerStyle> <ItemsControl.Items> Test item </ItemsControl.Items> <ItemsControl.ItemTemplate> <DataTemplate> <Border Width="20" Height="20"> <Rectangle Fill="Red"/> </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 的基本实现使用香草ItemsControl.ItemContainerStyle。需要注意的是,如果您不将UI元素用作项目,则需要使用自定义项目控件将其包装为一个项目(请参见this answer on setting the container style):
Interaction.Behaviors
  1. 使用 <ItemsControl.ItemContainerStyle> <Style> <Setter Property="beh:AddCollectionsToSetter.Behaviors"> <Setter.Value> <beh:BehaviorCollection> <ei:MouseDragElementBehavior ConstrainToParentBounds="True"/> </beh:BehaviorCollection> </Setter.Value> </Setter> </Style> </ItemsControl.ItemContainerStyle> 附加互动。这有点涉及,因为附加的AddCollectionsToSetter.Behaviors属性只有一个setter:
BehaviorCollection

为此,我必须创建一个单独的附加属性 public static class AddCollectionsToSetter { #region Behaviors Dependency Property (Attached) /// <summary>Gets the behaviours to add.</summary> public static BehaviorCollection GetBehaviors(DependencyObject obj) { return (BehaviorCollection)obj.GetValue(BehaviorsProperty); } /// <summary>Sets the behaviours to add.</summary> public static void SetBehaviors(DependencyObject obj, BehaviorCollection value) { obj.SetValue(AddCollectionsToSetter.BehaviorsProperty, value); } /// <summary>DependencyProperty backing store for <see cref="Behaviors"/>. Represents the behaviours to add.</summary> /// <remarks></remarks> public static readonly DependencyProperty BehaviorsProperty = DependencyProperty.RegisterAttached("Behaviors", typeof(BehaviorCollection), typeof(AddCollectionsToSetter), new PropertyMetadata(null, BehaviorsPropertyChanged)); private static void BehaviorsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var oldBehaviors = (BehaviorCollection)e.OldValue; var newBehaviors = (BehaviorCollection)e.NewValue; var interaction = Interaction.GetBehaviors(d); interaction.RemoveRange(oldBehaviors); // extension method, simple iterate and remove interaction.AddRange(newBehaviors.Clone()); // extension method, simple iterate and add } #endregion Behaviors Dependency Property (Attached) } public class BehaviorCollection : FreezableCollection<System.Windows.Interactivity.Behavior> { public BehaviorCollection() : base() { } public BehaviorCollection(int capacity) : base(capacity) { } public BehaviorCollection(IEnumerable<System.Windows.Interactivity.Behavior> behaviors) : base(behaviors) { } } ,该属性是可读/写的,另外一个; this is practicaly the SAR instruction, ; the mask for the absolute value is ; number >> (sizeof(short)) * CHAR_BIT -1) ; number >> (2 * 8) - 1 = 15 ; so normaly we would do SAR bx, 15 and done mov bl, ah ; BX = AX>>8 add bx, bx ; BX <<= 1 neg bh ; 0 or -1 mov bl, bh ; duplicate the full BX mov cx, ax ; add cx, bx ; the number + mask xor bx, cx ; (number+mask) ^ mask 则允许添加交互。

var test = JSON.parse(`<%= raw Item.select('promCode','baseCode','monadaMe','price','fpa').where(:itemName => '${itemname}' ).collect { |p| [p.promCode, p.baseCode, p.monadaMe, p.price, p.fpa] }.join("\n").gsub("\n", " ").split(" ")%>`);