添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

reference website : https://stackoverflow.com/questions/5913792/wpf-canvas-how-to-add-children-dynamically-with-mvvm-code-behind

Requirement:

To draw one Bitmap Image and rectangle(s) based on the collection of points. The rectangle should exactly fit on the pixels location over the image. There is also some text need to be added inside the rectangle.

The Image will be always only one and the rectangles will be dynamically added.

Current Solution:

Have a canvas with Image Control. Add the the dynamic code under the code behind file ViewImageResult.xaml.cs.

private void DrawResult(int left, int right, int width, int height)
        Border bord = new Border();
        bord.BorderThickness = new Thickness(1);
        bord.BorderBrush = Brushes.Red;
        bord.Width = width;
        bord.Height = height;
        _mainCanvas.Children.Add(bord);
        Canvas.SetLeft(bord, left);
        Canvas.SetTop(bord, right);
    }

Issue:

Since i follow MVVM pattern, the collection of points for rectangle is in my ViewModel file ViewImageResultModel.cs. I am not able to add the child rectangle dynamically from the ViewModel file.

wpf mvvm canvas dynamic children

Share

Improve this question

Follow

edited Mar 30 '20 at 14:41

ΩmegaMan

23.9k99 gold badges8080 silver badges9898 bronze badges

asked May 6 '11 at 15:44

Sathya Ram

51111 gold badge66 silver badges1010 bronze badges

Add a comment


2 Answers

Active Oldest Votes


48

ItemsControl is your friend:

<Grid>
    <Image Source="..."/>
    <ItemsControl ItemsSource="{Binding Points}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Red" BorderThickness="1" Width="{Binding Width}" Height="{Binding Height}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

The above assumes your VM exposes a collection of points via a Points property, and that each point VM has X , Y , Width , and Height properties.

Share

Improve this answer

Follow

edited Sep 27 '11 at 15:24

Tim Cooper

146k3636 gold badges309309 silver badges265265 bronze badges

answered May 6 '11 at 17:34

Kent Boogaart

167k3434 gold badges378378 silver badges382382 bronze badges

  • 2

    Many Thanks Kent. That works fabulous with small change <Canvas IsItemsHost="True" />
    Sathya Ram Jun 13 '11 at 10:30
  • 2

    That... that is just beautiful.
    gwiazdorrr Feb 28 '12 at 8:54

Add a comment


0

Added IsItemsHost="True" to the Canvas of Kent's solution:

<Grid>
    <Image Source="..."/>
    <ItemsControl ItemsSource="{Binding Points}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas  IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Red" BorderThickness="1" Width="{Binding Width}" Height="{Binding Height}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>