在 WPF 中使用 MVVM 将 n 个矩形添加到画布

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22324359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:11:26  来源:igfitidea点击:

Add n rectangles to canvas with MVVM in WPF

c#wpfuser-interfacecanvasmvvm

提问by Philipp Eger

I want to add a set of rectangles to the main window of my mvvm application. In my viewModel I've got a collection of objects which I convert to System.Windows.Shapes.Rectangle classes with a converter (code below):

我想向我的 mvvm 应用程序的主窗口添加一组矩形。在我的 viewModel 中,我有一组对象,我使用转换器(下面的代码)将这些对象转换为 System.Windows.Shapes.Rectangle 类:

ViewModel:

视图模型:

RecognizedValueViewModel 
{
    public ObservableCollection<BarcodeElement> BarcodeElements
    {
        get { return _BarcodeElements; }
        set { _BarcodeElements = value; }
    }

    public RecognizedValueViewModel()
    {
        BarcodeElements = InitializeBarcodeElements();
    }
}

Converter:

转换器:

public BarcodeElementToRectangleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Rectangle barcodeRectangle = GetRectangleFromBarcodeElement(value as BarcodeElement);

        return barcodeRectangle;
    }
}

The rectangles should be shown in a canvas in my MainWindow:

矩形应显示在我的 MainWindow 的画布中:

<Canvas x:Name="Canvas_Image_Main">
    <!-- Show rectangles here -->
</Canvas>

I would add Rectangles to canvas in code but I don't now how many rectangles are there at runtime. Is there a way how I can achieve this? Tank you.

我会在代码中将矩形添加到画布,但我现在不知道运行时有多少矩形。有什么办法可以实现这一目标吗?保护你。

回答by Clemens

In a proper MVVM approach you would have a view model with an abstract representation of a list of rectangles, e.g. like this:

在适当的 MVVM 方法中,您将拥有一个带有矩形列表抽象表示的视图模型,例如:

public class RectItem
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Width { get; set; }
    public double Height { get; set; }
}

public class ViewModel
{
    public ObservableCollection<RectItem> RectItems { get; set; }
}

Then you would have a view that uses an ItemsControl to visualize a collection of such Rectitems. The ItemsControl would have a Canvas as its ItemsPaneland an appropriate ItemContainerStyleand ItemTemplatewhich each bind to the appropriate view model properties. It might look like this:

然后,您将拥有一个使用 ItemsControl 来可视化此类Rect项目集合的视图。ItemsControl的将具有画布作为其ItemsPanel与一个适当的ItemContainerStyleItemTemplate其各自结合到相应的视图模型属性。它可能看起来像这样:

<ItemsControl ItemsSource="{Binding RectItems}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="Black"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


An alternative without Bindings in Style Setters (which don't work in UWP) might look like this:

在样式设置器中没有绑定的替代方案(在 UWP 中不起作用)可能如下所示:

<ItemsControl ItemsSource="{Binding RectItems}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="Black">
                <Rectangle.RenderTransform>
                    <TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
                </Rectangle.RenderTransform>
            </Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

回答by Abhinav Sharma

You can bind the collection of rectangles to an ItemControl and set its height, width and margin:

您可以将矩形集合绑定到 ItemControl 并设置其高度、宽度和边距:

<ItemsControl  ItemsSource="{Binding Path=RectangleCollection,Mode=TwoWay}">
    <ItemsControl.ItemTemplate>
        <DataTemplate >
            <Canvas>
                <Rectangle Stroke="Black" Heigth={some converter} Width={some converter} Margin={Some Converter}>
            </Canvas>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemControl>

Just an idea to get you started...

只是一个让你开始的想法......