我正在尝试使用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
.据我所知,您已经正确使用它,这只是命名。