gpt4 book ai didi

C# WPF 参数异常 : Specified Visual is already a child of another Visual or the root of a CompositionTarget

转载 作者:行者123 更新时间:2023-11-30 16:13:17 24 4
gpt4 key购买 nike

我得到了一个包含图像及其左/上位置的列表,我将其添加到 Canvas 中。但是,我希望能够毫无问题地将相同的图像(相同的来源)添加到 Canvas 。

当我只使用下面的代码时:

Image img = ImagesList[i].Image; // ImagesList is a list of MyClass (containing Image Image; double Left; double Top)
img.Name = "img" + i; // where i is the nr in the list
Canvas.SetLeft(img, ImagesList[i].Left); // Left default = 0
Canvas.SetTop(img, ImagesList[i].Top); // Top default = 0
MyCanvas.Children.Add(img);
OnPropertyChanged("MyCanvas");

当相同的图像(-source)已经出现在 Canvas 上(具有不同的左/上位置和名称)时,我得到以下异常:

ArgumentException: Specified Visual is already a child of another Visual or the root of a CompositionTarget.

所以我知道不允许将相同的 UIElement(在我的例子中是图像)添加到相同的 Canvas 。

我将我的代码修改为:

// If the Image already exists on the Canvas, we need to make a clone of the image
if (MyCanvas.Children.Contains(img)) {
Image cloneImg = new Image();
cloneImg.Source = img.Source;
cloneImg.Name = img.Name;
Canvas.SetLeft(cloneImg, Left);
Canvas.SetTop(cloneImg, Top);
MyCanvas.Children.Add(cloneImg);
}
else
MyCanvas.Children.Add(img);
OnPropertyChanged("MyCanvas");

这解决了错误,但现在我遇到了一个新问题。我确实在 Canvas 上得到了两个图像,但是已经存在的图像将其位置(左侧和顶部)重置为 0,0(与新的相同)添加图像),当我进行 Console.Write-test 时,我还注意到 Canvas 上的两个图像的名称现在相同。

克隆使第一个图像的名称、左侧、顶部(可能还有其他东西)与第二个图像(“克隆”)相同,我做错了什么?

预先感谢您的回复。


编辑:根据 Clemens 的建议,我将 xaml 更改为:

<Canvas Name="MyCanvas" Background="LimeGreen"/>

收件人:

<ItemsControl ItemsSource="{Binding MyField.ImagesList}"> <!-- MyField is the class where I have my list -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Name="FieldCanvas" Background="LimeGreen" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
<Setter Property="Canvas.Top" Value="{Binding Top}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageSource}" AllowDrop="True" PreviewMouseLeftButtonDown="Image_PreviewMouseLeftButtonDown" PreviewMouseMove="Image_PreviewMouseMove" PreviewMouseLeftButtonUp="Image_PreviewMouseLeftButtonUp"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

ImagesList 现在还包含 BitmapImage ImagesSource 而不是 Image Image。

但我还不能测试它,因为它给出了一堆错误。例如,我在 ViewModel 的构造函数中使用 Canvas 作为参数,但现在它位于 ItemsControl 中,我不知道如何访问它。而且我还在我的 MouseEvent 函数中遇到了一些错误,我使用 img.Parent 获取 Canvas(上面的代码不再工作)和 canvas.Children 获取所有图像,包括它们的 ZIndex(这也是'不再工作了)。


编辑 2/解决方案:

在撤消上面的编辑后,因为我的其他糟糕的代码部分出现了很多错误,除了我保存在列表中的 ImageSource 而不是图像本身,结果证明它现在可以工作了。

最佳答案

您通常会使用 ItemsControl 来执行此操作,它具有作为 ItemsPanel 的 Canvas 和绑定(bind) Canvas.Left 的 ItemContainerStyle Canvas.Top 属性到数据项类中的适当属性。

如果这是您的数据项类:

public class ImageItem
{
public string Source { get; set; }
public double Left { get; set; }
public double Top { get; set; }
}

public class ViewModel
{
public ViewModel()
{
ImageItems = new ObservableCollection<ImageItem>();
}

public ObservableCollection<ImageItem> ImageItems { get; private set; }
}

ItemsControl 的 XAML 如下所示。请注意,它的 ItemsSource 属性绑定(bind)到 ViewModel 类中的 ImageItems 属性。

<ItemsControl ItemsSource="{Binding ImageItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=Left}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Top}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=Source}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

MainWindow 初始化代码中的某处:

var vm = new ViewModel();
DataContext = vm;

vm.ImageItems.Add(
new ImageItem
{
Source = @"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg",
Left = 100,
Top = 50
});
vm.ImageItems.Add(
new ImageItem
{
Source = @"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg",
Left = 200,
Top = 100
});

关于C# WPF 参数异常 : Specified Visual is already a child of another Visual or the root of a CompositionTarget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21883586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com