通过MVVM UWP在Grid中动态生成元素

时间:2017-04-10 09:21:43

标签: mvvm uwp dynamically-generated

我正在尝试使用ItemsControl在网格中动态生成项目。我希望网格只有一行和2 *(元素数)列,因此元素之间的空间可以相等。这些物品应该获得容器中所有可用的水平空间,并且它们之间应该是粗线。 我将应该保存项目的容器绑定在页面的代码隐藏中:

private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        ((MainViewModel)this.DataContext).Container = this.FindName("algContainer") as Grid;
    }

每个项目的视图模型是:

public class ElementViewModel : BaseViewModel
{
    private int _column;
    private double _width;
    private double _height;
    private double _strokeTickness;
    private Brush _fill;
    private SolidColorBrush _stroke;
    private VerticalAlignment _verticalAlignment;

    public ElementViewModel()
    {

    }

    public double Width
    {
        get { return _width; }
        set
        {
            _width = value;
            NotifyPropertyChanged();
        }
    }

    public double Height
    {
        get { return _height; }
        set
        {
            _height = value;
            NotifyPropertyChanged();
        }
    }

    public Brush Fill
    {
        get { return _fill; }
        set
        {
            _fill = value;
            NotifyPropertyChanged();
        }
    }

    public VerticalAlignment VerticalAlignment
    {
        get { return _verticalAlignment; }
        set
        {
            _verticalAlignment = value;
            NotifyPropertyChanged();
        }
    }

    public double StrokeThickness
    {
        get { return _strokeTickness; }
        set
        {
            _strokeTickness = value;
            NotifyPropertyChanged();
        }
    }

    public SolidColorBrush Stroke
    {
        get { return _stroke; }
        set
        {
            _stroke = value;
            NotifyPropertyChanged();
        }
    }

    public int Column
    {
        get { return _column; }
        set
        {
            _column = value;
            NotifyPropertyChanged();
        }
    }
}

生成元素的方法在页面视图模型中:

public ICommand Sort
    {
        get
        {
            if (this._sortCommand == null)
            {
                this._sortCommand = new RelayCommand(this.PerformSort);
            }
            return this._sortCommand;
        }

    }

private void PerformSort()
    {
        this.ElementCollection = PopulateElements();
    }

private List<ElementViewModel> PopulateElements()
    {
        var heightsList = GenerateRadnomNumbers(this.ElementsCount, (int)this.Container.ActualHeight);
        double width = this.Container.ActualWidth / this.ElementsCount;
        var collection = new List<ElementViewModel>();

        this.Container.ColumnDefinitions.Clear();
        this.Container.Children.Clear();

        for (int i = 0, j = 1; i < this.ElementsCount; i++, j += 2)
        {
            var emptyColDef = new ColumnDefinition();
            var elementColDef = new ColumnDefinition();
            var element = new ElementViewModel();

            emptyColDef.Width = GridLength.Auto;
            elementColDef.Width = new GridLength(1, GridUnitType.Star);

            this.Container.ColumnDefinitions.Add(emptyColDef);
            this.Container.ColumnDefinitions.Add(elementColDef);

            element.Width = width;
            element.Height = heightsList[i];
            element.Column = j;
            element.Fill = new SolidColorBrush(Colors.Black);
            element.Stroke = new SolidColorBrush(Colors.White);
            element.StrokeThickness = 1;
            element.VerticalAlignment = VerticalAlignment.Bottom;

            collection.Add(element);
        }

        return collection;
    }

我想填充的XAML是:

<Grid  Grid.Row="1" Grid.ColumnSpan="2"  Margin="12">
        <ItemsControl ItemsSource="{Binding ElementCollection, Mode=TwoWay}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid x:Name="algContainer" Background="White"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Fill}" StrokeThickness="{Binding StrokeThickness}" Stroke="{Binding Stroke}" Grid.Column="{Binding Column}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
<Border Margin="12"  Grid.Row="4" Grid.Column="0">
            <Button x:Name="sortButton" Content="Sort" VerticalAlignment="Center" HorizontalAlignment="Center" Width="80" Command="{Binding Sort}"/>
        </Border>

一切正常但元素(矩形)放在一列中有很多行,但我希望它们在一行中有很多列。 ItemsControl中的问题是我应该如何更改它?

1 个答案:

答案 0 :(得分:0)

您可以使用横向ItemsPanel,如下所示:

<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsStackPanel
                Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

我认为ViewModelModel之间存在一点混淆。 ElementViewModel只是我眼中的正常Model(因为它只提供数据而没有命令),所以我会从ObservableObject延伸(MVVM light已提供) ,并将其重命名为ElementModel。据我所知,你已经正确使用它了,这只是命名。