以WPVM方式在WPF中动态创建圆圈

时间:2013-09-26 06:40:21

标签: wpf mvvm

我正在学习WPF和新手。我有这个要求。在视图模型中,我有一个时间跨度对象。我想将时间长度显示为"每小时填充一个圆圈"。以WPF方式执行此操作的最佳方式是什么。我试过了ItemsTemplate但却找不到办法。

3 个答案:

答案 0 :(得分:2)

看看这个article about creating a Rating Control它会非常相似。

关于这个的唯一MVVM可能是你如何收集应该在控件中显示的实际值。但构建控件与MVVM没什么关系。

如果您遇到困难并尝试提出具体问题,请告知我们。

答案 1 :(得分:0)

一个选项是创建自定义控件,该控件将生成以更正代码中的圆圈数,但如果您更喜欢主要使用XAML,则可以选择几个选项。

如果您希望在面板内生成圆圈,可以使用ItemsControl执行生成。生成的项目是圆圈,因此您需要一个视图模型属性,每个整小时都有一个元素。这些元素没有任何属性,只能是Object类型:

public ObservableCollection<Object> Items { get; private set; }

您可以更新集合中的对象数量:

Items.Clear();
var item = new Object();
for (var i = 0; i < timeSpan.Hours; i += 1)
    Items.Add(item);

然后是一个简单的视图:

<ItemsControl ItemsSource="{Binding Items}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Ellipse Width="25" Height="25" Fill="Black" StrokeThickness="0" Margin="10"/>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

如果您想以使用面板难以做到的方式布局圆圈,您可以在XAML中手动布局24个圆圈。然后,您可以使用值转换器根据表示小时数的视图模型属性隐藏或显示每个圆:

// Remember to fire INotifyPropertyChanged.PropertyChanged when value changes.
public Int32 Hours { get; private set; }

然后,值转换器会将数字转换为可见性:

class VisibilityConverter : IValueConverter {

  public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture) {
    var hours = System.Convert.ToInt32(value);
    var visibleBelow = System.Convert.ToInt32(parameter);
    // Alternatively use Visibility.Collapsed to completely remove the circle.
    return hours <= visibleBelow ? Visibility.Visible : Visibility.Hidden;
  }

  public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture) {
    throw new NotImplementedException();
  }

}

然后,每个Ellipse都会使用标识Visibility小时的HoursConverterParameter绑定到Ellipse属性:

<Ellipse
  Visibility="{Binding Hours, Converter={StaticResource VisibilityConverter}, ConverterParameter=3}"/>

答案 2 :(得分:0)

有很多方法可以实现这一目标。这是您可以在原始XAML中执行的操作

  • ItemsControl数据绑定到由...生成的布尔值集合 你的视图模型 - 代表每小时一个bool。
  • ItemsControl.ItemTemplate设置为包含Ellipse的模板 相同的高度和宽度以及[颜色]
  • 的边框
  • 使用Actions / behaviors设置Ellipse的填充 [color]当DataContext等于System.Boolean时 真

使用此方法,每次其中一个更改时,您将需要在整个布尔集合上调用raise PropertyChanged。