【发布时间】:2014-04-10 14:00:39
【问题描述】:
我一直在开发我的第一个 MVVM WPF 应用程序,我想在其中绘制一个包含节点和边的图形。目前,我正在视图后面的代码中执行所有绘图逻辑,迭代节点,相应地创建形状并将它们添加到画布中。
因为我不想跟踪形状,只想根据给定的数据(即节点)绘制它们,所以我决定创建一个 ObservableCollection 的 Nodes 和Edges,并将ItemsControl 绑定到这些以自动绘制形状。
现在我专注于绘制节点,并提出了以下 XAML 代码:
<ItemsControl x:Name="ItemsControlCanvas" ItemsSource="{Binding Path=Nodes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.LayoutTransform>
<ScaleTransform ScaleX="{Binding ?}" ScaleY="{Binding ?}"/>
</Canvas.LayoutTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="Blue" Width="4" Height="4" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=Position.Y}" />
<Setter Property="Canvas.Left" Value="{Binding Path=Position.X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
在我看来,当用户在画布上滚动时,我设置了两个属性 ScaleX 和 ScaleY。在我早期版本的代码中,我将使用这些属性创建一个 ScaleTransform,并使用 LayoutTransform 将其应用于命名的画布。
public partial class GraphOverview : Page
{
public double ScaleX { get; set; }
public double ScaleY { get; set; }
这个版本的问题是我无法让它在我的新 XAML 代码中工作。我希望ItemsPanelTemplate 中ScaleTransform 的ScaleX 和ScaleY 属性绑定到我认为的属性。只是,正常的ElementName 绑定由于某种原因不起作用。更清楚地说,画布可能不知道视图,我假设因为它是一个模板。此外,我无法从后面的代码中调用画布,即使它有名称。
我尝试了几种解决方案,摸索RelativeResources 等,但我想我不明白为什么ItemsPanelTemplate 与XAML 代码中的其他所有内容如此脱节。提前致谢!
更新
也许我应该澄清一下,通过将 ScaleX 和 ScaleY 属性移动到 ViewModel 并绑定到这些属性,可以轻松解决此问题。但在我看来,此类特定于 View 的属性不应驻留在 ViewModel 中。
【问题讨论】: