我有一个代码,可以让您在屏幕上创建对象,有一个按钮面板,单击按钮可以在 Canvas 上创建图像/对象,我无法将其他图像放置在Canvas中,因此可以将多个图像显示出来,链接到先前创建的问题:WPF C # Display objects (2d Map)
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas>
<Image x:Name="injWell" Source="/Resources/injectionWell.png"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="40" Height="40"
Stretch="Fill" StretchDirection="Both" IsHitTestVisible="False"/>
<Image x:Name="injWellNot" Source="/Resources/injectionWellNot.png"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="40" Height="40"
Stretch="Fill" StretchDirection="Both" IsHitTestVisible="False"/>
<TextBlock Canvas.Top="-20" Canvas.Left="-40" Width="100"
TextAlignment="Center" Text="{Binding Name}" FontWeight="Bold"
IsHitTestVisible="False"
Visibility="{Binding DataContext.ShowNames,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window},
Converter={StaticResource BoolToVisibilityConverter}}"/>
<TextBlock Canvas.Left="30" Canvas.Top="10"
Text="{Binding X, StringFormat='{}X = {0}'}"
IsHitTestVisible="False"
Visibility="Collapsed" x:Name="XText"/>
<TextBlock Canvas.Left="30" Canvas.Top="25"
Text="{Binding Y, StringFormat='{}Y = {0}'}"
IsHitTestVisible="False"
Visibility="Collapsed" x:Name="YText"/>
</Canvas>
<ControlTemplate.Triggers>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="injWell" Property="Source" Value="/Resources/injectionWell.png"/>
<Setter TargetName="injWellNot" Property="Source" Value="/Resources/injectionWellNot.png"/>
</Trigger>
<DataTrigger Binding="{Binding DataContext.ShowAllCoordinates, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Value="True">
<Setter TargetName="XText" Property="Visibility" Value="Visible"/>
<Setter TargetName="YText" Property="Visibility" Value="Visible"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True"/>
<Condition Binding="{Binding DataContext.ShowCurrentCoordinates, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="XText" Property="Visibility" Value="Visible"/>
<Setter TargetName="YText" Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</DataTemplate>
最佳答案
在这里要实现的关键是,您需要呈现项目列表,在MVVM中,您可以使用ItemsControl来实现。 (您也可以使用ListView,但是它们实现了您几乎肯定不会想要的其他功能,例如项目选择等)。最终,您希望所有图形对象都显示在Canvas上,因此您需要覆盖ItemsPanel属性,并将其中一个放置在ItemsPanelTemplate中。然后,需要将每个元素放置在Canvas上,因此您需要设置ItemContainerStyle并在那里设置Canvas.Left和Canvas.Top属性(一个常见的错误是对元素本身进行操作,但是将它们放置在一个容器,因此您必须在该容器上执行此操作)。将所有这些放在一起,您将获得如下所示的内容:
<ItemsControl ItemsSource="{Binding MyGraphicsViewModels}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
因此,MyGraphicsViewModels通常会在您的 View 模型中列出您已创建的某些基类(例如BaseGraphicsViewModel),然后将其子类化为您要绘制的所有不同类型的图形项。最后的难题是添加DataTemplates以指定您希望如何在 View 中表示每种 View 模型类型:
<DataTemplate DataType="{x:Type vm:DerivedGraphicsObjectViewModel}">
<Rectangle Fill="Blue" Width="64" Height="64" />
</DataTemplate>
有关使用触发器而不是DataTemplates的更全面的示例,请查看过去的my answer to this SO question。
关于c# - Canvas 上的MVVM WPF图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516683/