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



我正在尝试使用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>

一切正常,但元素(矩形(放置在一列中,其中包含许多行,但我希望它们位于具有许多列的一行中。问题是否出在项目控件中,我应该如何更改它?

您可以使用水平ItemsPanel,如下所示:

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

我认为您在ViewModel s和Model s之间有一个小小的混淆。ElementViewModel在我看来只是一个普通的Model(因为它只提供数据而不提供命令(,所以我会从ObservableObject(MVVM light已经提供(扩展,并将其重命名为 ElementModel .据我所知,您已经正确使用它,这只是命名。

最新更新