【问题标题】:How can I drop a ListViewItem onto a Canvas and render the image, the Item contains?如何将 ListViewItem 拖放到 Canvas 上并渲染项目包含的图像?
【发布时间】:2019-11-19 22:40:48
【问题描述】:

我有一个“模块”类型的自定义对象,我在其中存储了一个图像和一个名称。这些对象存储在 ListView 中,我将它们拖放到 Canvas 上,这样我就可以排列它们(有点像拼图)。首先,我只是画了图像:

var module = e.Data.GetData("MyFormat") as Module;
Canvas CanvasView = sender as Canvas;

Image image = new Image();
image.Source = module.ModuleImage;

Point enterPoint = e.GetPosition(this.moduleCanvas);

Point PointToDraw = new Point(0, 0);
PointToDraw.X = enterPoint.X - DropPosition.X;
PointToDraw.Y = enterPoint.Y - DropPosition.Y;

//+35 and +43 so the Module gets dropped in the way you picked it up
image.SetValue(Canvas.LeftProperty, PointToDraw.X + 35);
image.SetValue(Canvas.TopProperty, PointToDraw.Y + 43);

CanvasView.Children.Add(image);

但后来我意识到,我需要一个对象在画布上,而不仅仅是一个图像,所以我尝试了这个:

ListViewItem lvitem = new ListViewItem();
var module = e.Data.GetData("MyFormat") as Module;
Canvas CanvasView = sender as Canvas;

lvitem.Content = module;
CanvasView.Children.Add(lvitem);

但这当然不会在画布上渲染图像。它只是告诉我MyNamespace.Module。如何让 Canvas 呈现 ListViewItem 包含的对象的图像?

【问题讨论】:

  • 使画布成为项目控件的项目面板。将 itemssource 绑定到 itemviewmodel 的集合。日期模板 itemviewmodel 到任何你想要的。每个项目都在一个容器中。将 canvas.left 和 canvas.top 绑定到 itemviewmodel 中的 x 和 y 属性。如果你用谷歌搜索,你应该能够找到一堆如何做到这一点的例子。很确定我以前在 msdn 上发过帖子。

标签: c# wpf canvas


【解决方案1】:

如果您的Module 类的Image 属性返回一个实际的Image 元素,您可以将Content 属性设置为这个:

lvitem.Content = module.Image;

如果Image 返回一个路径,您可以将Content 属性设置为带有ContentTemplateContentTemplate,您可以使用FrameworkElementFactoryXamlReader.Parse 以编程方式创建该属性。在ContentTemplate 中,您定义Image 元素:

ContentControl cc = new ContentControl();
cc.Content = new LongTextConverter();

FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(Image));
frameworkElementFactory.SetBinding(Image.SourceProperty, new Binding("Image"));
cc.ContentTemplate = new DataTemplate() { VisualTree = frameworkElementFactory };

lvitem.Content = cc;

或者使用ListViewCanvas 作为ItemsPanel。有关示例,请参阅this answer。然后,您可以将ListViewItemsSource 设置为IEnumerable<Module>,并定义将应用于每个ModuleItemTemplate

【讨论】:

  • 嗯,Module 包含一个 ImageSource,但即使我会这样做 lvitem.Content = module.Image; 我仍然只有画布上的图像而不是整个对象
  • @DudeWhoWantsToLearn:我虽然这就是你想要的。但是你仍然可以使用ContentPresenterContentTemplate,正如我所建议的那样。显然,Canvas 不应该知道你想如何呈现Module 对象而不告诉它。
  • 我想要一个类似 winforms 的编辑器,我可以在其中从列表中拖放对象、重新排序并让它们交换数据。就像一个拼图编辑器,当你完成时,拼图会告诉你
  • 这与您的问题“如何将 ListViewItem 拖放到画布上并渲染图像,项目包含?”有什么关系?我相信它已经得到了回答。
  • 我需要画布上的对象,但不是“mynamespace.module”,而是要渲染模块的图像。不只是图像,我需要它背后的对象。就像一个列表视图。您将对象存储在其中,但您可以选择如何显示项目。我的有下面的图像和名称。但它仍然是一个对象,我可以使用
猜你喜欢
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 2011-10-08
  • 2014-03-16
相关资源
最近更新 更多