Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
78 views
in Technique[技术] by (71.8m points)

c# - Add Shape information to a ListView when its created

Im creating shapes(rectangles, ellipse, line) in to a canvas. And then i have in another window a listview where i need to input the information of the shape(such like position, size, what shape it is).

I have this code in XAML in another window:

    <ListView Name="Information">

        <ListView.View>
            <GridView>
                <GridViewColumn Header="Type"/>
                <GridViewColumn Header="PositionX"/>
                <GridViewColumn Header="PositionY"/>
                <GridViewColumn Header="Width" DisplayMemberBinding="{Binding ActualWidth}"/>
                <GridViewColumn Header="Height" DisplayMemberBinding="{Binding ActualHeight}"/>
            </GridView>
        </ListView.View>

    </ListView>

and in c# of the main window, i have an observable collection and this code:

ObservableCollection<Shape> shapes = new ObservableCollection<Shape>();

myRect.Width = var1;
myRect.Height = var2;
Page.Children.Add(myRect);
Canvas.SetLeft(myRect, posx);
Canvas.SetTop(myRect, posy);

shapes.Add(myRect);
2ndwindow.Information.ItemsSource = shapes; // this is working because the 2ndwindow is owned by the mainwindow

EDIT: i managed to bind the width and height, but i dont know how to bind the position and the shape it is(rectangle or ellipse)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...