2017-04-10 2 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")을 Grid로; 이것은 MVVM이 아닙니다. DataTemplates를 사용해야합니다. 그들이 무엇인지 어떻게 사용되었는지 모를 경우 지금 연구하십시오. 데이터 템플릿만으로는 너무 복잡하기 때문에 사용자 정의 컨트롤을 만들고 그 안에 UI 작업을 캡슐화하십시오. 공용 종속성 속성을 공개하고 해당 속성을보기 모델에 바인딩합니다 (또는보기 모델에 격자에 넣어야하는 항목이 들어있는 속성). – Will

답변

0

이 같은 수평 ItemsPanel을 사용할 수 있습니다

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

난 당신이 ViewModel들과 Model의 사이에 작은 혼란을 것 같아요. ElementViewModel은 내 눈에 보통 Model이며 (데이터와 명령을 제공하지 않음) ObservableObject (MVVM light은 이미 제공)에서 확장하여 ElementModel으로 이름을 바꿉니다. 당신이 이미 말할 수있는 한 그것을 이미 정확하게 사용하고 있습니다, 그것은 단지 명명입니다.

+0

StackPanel 계산을 사용하면 모든 항목의 너비가 잘못 계산됩니다. 나는 그것을 계산하는 몇 가지 방법을 시도했으나 요소가 컨테이너의 수평 공간을 더 많거나 적게 늘릴 때마다 시도했다. – PackMan0

+0

'StackPanel '은 항상 내용을 둘러싸도록 확장됩니다. 당신이 사용하고자하는 실제 너비 ("전체 너비")로''의 너비를 취할 수 있고 (Grid가 부모의 너비에 맞게 펼쳐지기 때문에) 계산에 기반 할 수 있습니다. –

관련 문제