0

我在 silverlight 中有一个图像编辑器,允许用户在画布上添加、操作和删除图像和文本元素。我注意到有时添加新元素时它的行为似乎很奇怪,例如它们将被放置在现有元素的后面。下面是添加图像元素的代码,以及它调用的 order elements 方法。我从其他人那里继承了这段代码,所以有时我无法理解他的意图。该代码似乎没有做它应该做的事情。

有人可以建议一种更好的方法来为我添加的元素分配 Z-Index 值吗?

我的工作区画布的 XAML -

<Canvas x:Name="pnlCanvas" HorizontalAlignment="Center" VerticalAlignment="Center" Height="{Binding Path=CanvasHeight, Mode=OneWay,UpdateSourceTrigger=Default}"
                        Width="{Binding Path=CanvasWidth, Mode=OneWay, UpdateSourceTrigger=Default}" >
                    <ItemsControl ItemsSource="{Binding Path=Elements, Mode=OneWay}"  >
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <Canvas Background="{Binding Path=CanvasBackground, Mode=OneWay}"
                                    Height="{Binding Path=CanvasHeight, Mode=OneWay,UpdateSourceTrigger=Default}"
                                    Width="{Binding Path=CanvasWidth, Mode=OneWay, UpdateSourceTrigger=Default}" />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>
                </Canvas>

添加图像元素 -

private void AddImageElement(object param)
    {
        bool? gotImage;
        string fileName;
        BitmapImage imageSource = GetImageFromLocalMachine(out gotImage, out fileName);
        OrderElements();

        if (gotImage == true)
        {
            Image image = new Image();
            image.Name = fileName;
            image.Source = imageSource;
            image.Height = imageSource.PixelHeight;
            image.Width = imageSource.PixelWidth;
            image.MaxHeight = imageSource.PixelHeight;
            image.MaxWidth = imageSource.PixelWidth;
            image.Cursor = Cursors.Hand;
            image.Tag = null;



            AddDraggingBehavior(image);
            image.MouseLeftButtonUp += element_MouseLeftButtonUp;

            this.Elements.Add(image);
            numberOfElements++;

            this.SelectedElement = image;
            this.SelectedImageElement = image;
        }
    }

订单元素 -

private void OrderElements()
    {
        var elList = (from element in this.Elements
                      orderby element.GetValue(Canvas.ZIndexProperty)
                      select element).ToList<FrameworkElement>();

        for (int i = 0; i < elList.Count; i++)
        {
            FrameworkElement fe = elList[i];
            fe.SetValue(Canvas.ZIndexProperty, i);

        }

        this.Elements = new ObservableCollection<FrameworkElement>(elList);

    }

一旦我解决了这个问题,我的最终意图是包含一个图层容器,比如在 Photoshop 等中,我将能够重新排序元素。希望有人可以帮助我朝那个方向前进。基本上我如何正确设置 Z-Index,因为我不认为这是这样做的。

4

1 回答 1

2

AnItemsControl将每个元素包装在一个<ContentPresenter>标签中,因此尽管 ZIndex 已在您的元素上设置,但它不会被应用,因为ZIndexonContentPresenter最重要

实际渲染的内容如下所示:

<Canvas>
    <ContentPresenter>
        <Image Canvas.ZIndex="0" />
    </ContentPresenter>
    <ContentPresenter>
        <Image Canvas.ZIndex="1" />
    </ContentPresenter>
    ...
</Canvas>

要解决此问题,请在 中设置ZIndexItemContainerStyle以便将其应用于ContentPresenter而不是 UI 元素

<ItemsControl.ItemContainerStyle>
    <Style>
        <Setter Property="Canvas.ZIndex" Value="{Binding Canvas.ZIndex}" />
    </Style>
</ItemsControl.ItemContainerStyle>

有关详细信息,请参阅我关于 WPF 的 ItemsControl 的博客文章的底部部分

编辑:

显然 Silverlight 没有ItemsContainerStyle用于ItemsControl.

ContentPresenter在这种情况下,只需为设置您的Canvas.ZIndex值的隐式样式ItemsControl.Resources

<ItemsControl.Resources>
    <Style TargetType="ContentPresenter">
        <Setter Property="Canvas.ZIndex" Value="{Binding Canvas.ZIndex}" />
    </Style>
</ItemsControl.Resources>
于 2012-09-20T15:42:28.620 回答