公开viewmodel以使用WPF绘制条形图

时间:2013-09-02 18:27:53

标签: wpf xaml data-binding mvvm

我正在构建一个WPF用户控件,它使用Rectangle显示一个简单的堆叠条。数据由viewmodel中的DependencyProperty提供,因此我可以将集合绑定到它。该模型如下所示:

public class BarPart {
  public Color Color { get; set; }
  public int Size { get; set; }
}

带有假宽度绑定的视图说明了意图:

<ItemsControl ItemsSource="{Binding ElementName=Root, Path=Data}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="{Binding TotalSize / Size * Root.Width}" Height="30">
                <Rectangle.Fill>
                    <SolidColorBrush Color="{Binding Color}" />
                </Rectangle.Fill>
            </Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

当然,尺寸不在用于显示的单位中,它可以是任何数字。这意味着我无法直接绑定到Size。然而,堆叠条的总宽度应该跨越用户控件的宽度。应使用大小的总和,相关BarPart的大小以及控件的总宽度来计算边界大小。

MVVM规定viewmodel不应该对视图有任何了解。那么这些计算和转换应该在哪里进行呢?

IValueConverter无法进行数学运算,因为它不知道所有BarPart大小的并且不知道要转换为显示的usercontrol的总宽度单元。

我不确定我有什么其他选择我做严格的MVVM。

1 个答案:

答案 0 :(得分:1)

您可以在转换器中使用MultiBinding,绑定类似于:

<Binding Path="Size"/>
<Binding ElementName="Root" Path="DataContext.TotalSize"/>
<Binding ElementName="Root" Path="ActualWidth"/>

包含条形的视图模型应计算TotalSize

(为了保持更新,您需要在所有栏上订阅属性更改,以便在任何栏的TotalSize更改时,您可以为Size触发属性更改事件。当然,如果栏添加/删除也需要完成。)