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

Posted

技术标签:

【中文标题】在 WPF 中使用 MVVM 将 n 个矩形添加到画布【英文标题】:Add n rectangles to canvas with MVVM in WPF 【发布时间】:2014-04-14 23:37:19 【问题描述】:

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

视图模型:

RecognizedValueViewModel 

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

    public RecognizedValueViewModel()
    
        BarcodeElements = InitializeBarcodeElements();
    

转换器:

public BarcodeElementToRectangleConverter : IValueConverter

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

        return barcodeRectangle;
    

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

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

我会在代码中将矩形添加到画布,但我现在不知道运行时有多少个矩形。有没有办法我可以做到这一点?坦克你。

【问题讨论】:

【参考方案1】:

在适当的 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; 

然后您将拥有一个使用 ItemsControl 来可视化此类Rect 项目集合的视图。 ItemsControl 将有一个 Canvas 作为其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>

在样式设置器中没有绑定的替代方案(在 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>

【讨论】:

我似乎无法在 UWP 中使用它,关于如何做到这一点的任何想法?因为你不能再绑定到 setter 属性了。 @NickN。见这里:***.com/q/40069749。虽然标记为重复,但我建议从答案中使用 RenderTransform 方法。【参考方案2】:

您可以将矩形集合绑定到 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>

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

【讨论】:

以上是关于在 WPF 中使用 MVVM 将 n 个矩形添加到画布的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 WPF 上使用 MVVM 模板来解决这个问题吗?

在 WPF MVVM 中添加多个用户控件的最佳控件?

如何在WPF中动态创建布局(MVVM模式)

附加到矩形线的火灾事件事件wpf c#

在 WPF MVVM Light 中多次绑定到 RelayCommand

WPF MVVM 将用户控件绑定到主窗口视图模型