为每个生成的项创建多个视觉效果

时间:2016-05-27 06:18:10

标签: wpf xaml itemscontrol

这是计划。我有一个ItemsControl,其中有两列Grid作为主要面板:

<ItemsControl>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="70" />
          <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="*" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
      </Grid>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

对于底层VM中的每个项目,我需要生成一个Label,它将进入第一列,而Rectangle将进入第二列。我怎样才能做到这一点?

<ItemsControl.ItemTemplate>
  <DataTemplate DataType="local:TimeSlotVM">
    ???
  </DataTemplate>
</ItemsControl.ItemTemplate>

2 个答案:

答案 0 :(得分:0)

如果您想使用Grid.Row附加属性,请通过GridHelper将此附加属性分配给父ContentPresenter。

视觉树将是这样的:

Grid
 -ContentPresenter Grid.Row="1"
  -Gird 
 -ContentPresenter Grid.Row="0"
  -Gird 
 -ContentPresenter Grid.Row="2"
  -Gird
 ...

GridHelper.cs

public class GridHelper
{
    public static readonly DependencyProperty GridRowProperty =
        DependencyProperty.RegisterAttached("GridRow", typeof(bool), typeof(GridHelper),
            new PropertyMetadata(false, new PropertyChangedCallback(OnGridRowPropertyChanged)));

    public static bool GetGridRow(DependencyObject d)
    {
        return (bool)d.GetValue(GridRowProperty);
    }

    public static void SetGridRow(DependencyObject d, bool value)
    {
        d.SetValue(GridRowProperty, value);
    }

    private static void OnGridRowPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Grid grid = d as Grid;
        bool gridRow = (bool)e.NewValue;

        if (gridRow)
        {
            // construct the required row definitions
            grid.LayoutUpdated += (s, e2) =>
            {
                // iterate over any new content presenters (i.e. instances of our DataTemplate)
                // that have been added to the grid
                var presenters = grid.Children.OfType<ContentPresenter>().ToList();
                foreach (var presenter in presenters)
                {
                    // the child of each DataTemplate
                    var itemGrid = VisualTreeHelper.GetChild(presenter, 0) as Grid;
                    if (itemGrid != null)
                    {
                        Grid.SetRow(presenter, Grid.GetRow(itemGrid));
                        if (Grid.GetRow(itemGrid) > grid.RowDefinitions.Count - 1)
                        {
                            presenter.Visibility = Visibility.Collapsed;
                        }
                    }
                }
            };
        }
    }
}

XAML

<ItemsControl ItemsSource="{Binding ItemList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Name="outer" local:GridHelper.GridRow="True">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    ...
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid Grid.Row="{Binding Row}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Content="{Binding Field}" />
                <Rectangle Grid.Row="{Binding Row}" Grid.Column="1" Fill="Blue" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

答案 1 :(得分:0)

如何使用UniformGrid和24 Empty TimeSlotVM的集合,然后将TimeSlotVM插入Collection中所需的位置,如下所示:

你的虚拟机中的

TimeSlotCollection=new ObservableCollection<TimeSlotVM>(new TimeSlotVM[24]);
            TimeSlotCollection.Insert(10,new TimeSlotVM());
            TimeSlotCollection.Insert(5, new TimeSlotVM());

并在您的视图中:

 <Grid>
        <Grid.Resources>
            <DataTemplate DataType="{x:Type local:TimeSlotVM}">
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="70" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Content="{Binding BindingField}" />
                    <Rectangle Grid.Column="1" Fill="Blue" />
                </Grid>
            </DataTemplate>
        </Grid.Resources>
        <ItemsControl ItemsSource="{Binding TimeSlotCollection}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="24"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>  
    </Grid>