Win*_*ter 4 c# data-binding wpf canvas mvvm
我正在尝试创建一个 WPF 画布控件,它可以绘制形状、曲线和文本块,选择和删除它们,因此我能想到的最好方法是使用 MVVM 将视图模型列表与 Canvas Children 绑定。
但是,Canvas Children 不能直接绑定。所以我有点卡住了。浏览过互联网但没有找到直接答案。我发现有人建议使用以下方法来实现绑定 Canvas Children,但我无法理解 ViewModels“Nodes”是什么类型,以及如何将不同的 Shapes、Curves 和 TextBlocks 转换为 Nodes。
任何帮助将不胜感激。提前致谢。
<ItemsControl ItemsSource="{Binding Path=Nodes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
Node您的视图模型应包含定义XPos和属性的基类YPos,以及特定节点类型的派生类,例如TextNode和ShapeNode:
public class Node
{
public double XPos { get; set; }
public double YPos { get; set; }
}
public class TextNode : Node
{
public string Text { get; set; }
}
public class ShapeNode : Node
{
public Geometry Geometry { get; set; }
public Brush Stroke { get; set; }
public Brush Fill { get; set; }
}
public class ViewModel
{
public ObservableCollection<Node> Nodes { get; } = new ObservableCollection<Node>();
}
Run Code Online (Sandbox Code Playgroud)
在 XAML 中,您可以为特定节点类型添加 DataTemplate,如下所示。有关详细信息,请参阅MSDN 上的数据模板概述文章。
<ItemsControl ItemsSource="{Binding Path=Nodes}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:TextNode}">
<TextBlock Text="{Binding Text}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ShapeNode}">
<Path Data="{Binding Geometry}" Stroke="{Binding Stroke}" Fill="{Binding Fill}"/>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
您现在可以将不同的节点添加到主视图模型类的实例,并将窗口的 DataContext 设置为该实例:
public MainWindow()
{
InitializeComponent();
var vm = new ViewModel();
vm.Nodes.Add(new TextNode
{
XPos = 50,
YPos = 100,
Text = "Hello, World."
});
vm.Nodes.Add(new ShapeNode
{
XPos = 100,
YPos = 200,
Geometry = new EllipseGeometry { RadiusX = 50, RadiusY = 50 },
Fill = Brushes.Red
});
DataContext = vm;
}
Run Code Online (Sandbox Code Playgroud)
如果您希望视图对节点的属性更改做出反应,则 Node 类应实现 INotifyPropertyChanged 接口。
如果项目应该是可选择的,则应将 ItemsControl 替换为 ListBox。ItemContainerStyle 的 TargetType 将为 ListBoxItem,您可以将其IsSelected属性绑定到 Node 类上的适当属性。
| 归档时间: |
|
| 查看次数: |
2890 次 |
| 最近记录: |