2017-04-10 31 views
0

我正在嘗試使用ItemsControl動態生成網格中的項目。我希望網格只有一行和2 *(元素數)列,所以元素之間的空間可以相等。這些物品應該獲得容器中所有可用的水平空間,並且它們之間應該是一條粗線。 我結合應該在頁面的代碼隱藏所保持的物品的容器,包括:通過MVVM動態生成網格中的元素UWP

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中的問題,我應該如何改變它?

+0

'((MainViewModel)this.DataContext).Container = this.FindName(「algContainer」)as Grid;'那不是MVVM。你應該使用DataTemplates。如果你不知道它們是什麼或者它們是如何使用的,那就去研究一下吧。如果您的需求對於單獨的數據模板來說太複雜,請創建一個用戶控件並將其UI工作封裝在其中。在其上公開依賴屬性並將它們綁定到視圖模型(或視圖模型包含需要放入網格的任何屬性)。 – Will

回答

0

您可以使用水平ItemsPanel,像這樣:

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

我認爲你有ViewModel S和Model S之間的小混亂。 ElementViewModel在我眼裏只是一個正常的Model(因爲它只提供數據和沒有命令),所以我將從ObservableObject(其中MVVM light已經提供)擴展,並將其重命名爲ElementModel。就我所知,你已經正確地使用它,這只是命名。

+0

當我使用像StackPanel計算每個項目的寬度是某種錯誤。我嘗試了幾種計算方法,但每次元素都會獲得或多或少的容器水平空間。 – PackMan0

+0

'StackPanel'始終擴展以環繞其內容。你可以將''的寬度作爲你想要使用的實際寬度(「全寬度」),並將計算結果作爲基礎(因爲'Grid'擴展爲適合其父寬度) –