2017-04-10 28 views
0

ItemsControlを使用してグリッド内の項目を動的に生成しようとしています。私はグリッドには1つの行と2 *(要素の数)の列を持たせて、要素間のスペースが等しくなるようにします。アイテムは、コンテナ内の利用可能なすべての水平スペースを取得する必要があり、それらの間に太い線が必要です。 Iは、ページのコードビハインドの項目を保持すべきである容器と結合: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> 

すべてが機能しますが、要素(四角形)は複数の行で1つの列に配置されますが、複数の列がある1つの行に配置されるようにします。 ItemsControlの問題です、どうすれば変更できますか?

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

私はあなたがViewModel秒とModelの間に小さな混乱を持っていると思う:

+0

'((MainViewModel)this.DataContext).Container = this.FindName(" algContainer ")をグリッドとして;これはMVVMではありません。 DataTemplatesを使用する必要があります。彼らが何であるか、どのように使用されているのかわからない場合は、今すぐ調査に行きましょう。データテンプレートだけでは複雑すぎる必要がある場合は、ユーザーコントロールを作成し、UIコントロールをその中にカプセル化します。パブリック依存関係プロパティを公開し、それらをビューモデル(またはビューモデルにグリッドに入れる必要があるプロパティを含むプロパティ)にバインドします。 – Will

答えて

0

あなたはこのように、水平ItemsPanelを使用することができます。 ElementViewModelは私の目にはちょうど普通のModelなので(データとコマンドを提供しないので)ObservableObjectMVVM lightは既に提供しています)から拡張し、ElementModelに改名します。あなたはすでに私が言うことができる限り、それを正しく使っています。それはちょうど命名です。

+0

StackPanel計算のようなものを使うと、どの項目の幅にも何らかの問題があります。私はそれを計算するためにいくつかの方法を試しましたが、要素がコンテナの水平空間の多かれ少なかれを取得するたびに試しました。 – PackMan0

+0

'StackPanel'は常にコンテンツを囲むように展開されます。実際に使用する幅( "全幅")として ''の幅をとり、 'Grid'がその親の幅に収まるように計算を行うことができます) –

関連する問題