在Silverlight中为画布上的图像和文本元素分配zIndex顺序



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

有人能建议一种更好的方法来为我添加的元素分配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,因为我不认为这是在做它。

ItemsControl将每个元素包装在<ContentPresenter>标记中,因此尽管ZIndex设置在元素上,但它不会被应用,因为ContentPresenter上的ZIndex才是的关键

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

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

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

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

有关更多信息,请参阅我关于WPF的ItemsControl的博客文章的底部

编辑:

显然Silverlight对于ItemsControl没有ItemsContainerStyle

在这种情况下,只需为ContentPresenter设置一个隐式样式,即可在ItemsControl.Resources中设置Canvas.ZIndex

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

最新更新