In a proper MVVM approach, you should have a view model with an abstract representation of a Shape (instead of a list of UI elements), e.g. like this:
public class ShapeData
{
public string Type { get; set; }
public Geometry Geometry { get; set; }
public Brush Fill { get; set; }
public Brush Stroke { get; set; }
public double StrokeThickness { get; set; }
}
public class ViewModel
{
public ObservableCollection<ShapeData> Shapes { get; }
= new ObservableCollection<ShapeData>();
}
You could now bind this view model to a view like shown below. The position and size of each shape is retrieved from the Bounds
property of the Geometry
of a shape object.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding Shapes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path Data="{Binding Geometry}"
Fill="{Binding Fill}"
Stroke="{Binding Stroke}"
StrokeThickness="{Binding StrokeThickness}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ListView Grid.Column="1" ItemsSource="{Binding Shapes}">
<ListView.View>
<GridView>
<GridViewColumn Header="Type"
DisplayMemberBinding="{Binding Type}"/>
<GridViewColumn Header="X"
DisplayMemberBinding="{Binding Geometry.Bounds.X}"/>
<GridViewColumn Header="Y"
DisplayMemberBinding="{Binding Geometry.Bounds.Y}"/>
<GridViewColumn Header="Width"
DisplayMemberBinding="{Binding Geometry.Bounds.Width}"/>
<GridViewColumn Header="Height"
DisplayMemberBinding="{Binding Geometry.Bounds.Height}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
You could create a view model instance in your window's constructor and add some sample data like this:
public MainWindow()
{
InitializeComponent();
var viewModel = new ViewModel();
viewModel.Shapes.Add(new ShapeData
{
Type = "Circle",
Geometry = new EllipseGeometry(new Point(100, 100), 50, 50),
Fill = Brushes.Orange,
Stroke = Brushes.Navy,
StrokeThickness = 2
});
viewModel.Shapes.Add(new ShapeData
{
Type = "Rectangle",
Geometry = new RectangleGeometry(new Rect(200, 50, 50, 100)),
Fill = Brushes.Yellow,
Stroke = Brushes.DarkGreen,
StrokeThickness = 2
});
DataContext = viewModel;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…