Преобразование содержимого сетки в ListView или другое для использования в шаблоне MVVM

У меня есть 5 X 4 Grid (код ниже), который работает так, как нужно для формы моих данных. Недавно я обнаружил, что практически невозможно передать сетку из модели представления в представление и связать ее с другой сеткой в ​​XAML, и при этом поддерживать шаблон MVVM - что является моей целью.

Проблема в том, что моя презентация требует, чтобы дочерние элементы были сгруппированы в отдельные ячейки, каждая из которых имеет 1 изображение и два элемента пользовательского интерфейса с текстовым блоком.

Кажется, что DataTable, DataSet, GridView, List и т. Д. Не имеют возможности добавлять несколько дочерних элементов в отдельные ячейки строк / столбцов для отображения. К сожалению, это не просто вставка изображения в заголовок столбца.

Кто-нибудь нашел другой вариант сделать подобное?

Спасибо,

Гленн

Ниже приведен пример сетки и изображение результирующего вида.

public void FormatGridCell()
{
   Random random = new Random();
   List<int> randomNumList = new List<int>();
   for (int i = 0; i < 50; i++)
      randomNumList.Add(random.Next(50));

   List<string> columHeader = new List<string>();
   columHeader.Add("Pitts");
   columHeader.Add("Vans");
   columHeader.Add("Lancair");
   columHeader.Add("Epic");

   List<string> rowHeader = new List<string>();
   rowHeader.Add("NORTH");
   rowHeader.Add("SOUTH");
   rowHeader.Add("EAST");
   rowHeader.Add("WEST");
   rowHeader.Add("CANADA");

   for (int x = 1; x < 5; x++)
   {
      var engineType= new TextBlock { Text = columHeader[x - 1] };
      engineType.SetValue(Grid.RowProperty, 0);
      engineType.SetValue(Grid.ColumnProperty, x);
      engineType.HorizontalAlignment = HorizontalAlignment.Center;
      this.airplaneGrid.Children.Add(engineType);

      for (int r = 1; r < 6; r++)
      {
         var dealerService = new TextBlock { Text = rowHeader[r - 1] };
         dealerService.SetValue(Grid.RowProperty, r);
         dealerService.SetValue(Grid.ColumnProperty, 0);
         dealerService.HorizontalAlignment = HorizontalAlignment.Center;
         this.airplaneGrid.Children.Add(dealerService);

         for (int i = 1; i < 6; i++)
         {
            // Bitmap path will be based on Type
            var modelImage = new Image { Width = 20, Height = 20 };
            var bitmapImage = new BitmapImage(new Uri(@"c:\personal\temp\dog.jpg"));
            modelImage.Source = bitmapImage;
            modelImage.SetValue(Grid.RowProperty, r);
            modelImage.SetValue(Grid.ColumnProperty, i);
            modelImage.HorizontalAlignment = HorizontalAlignment.Left;
            modelImage.VerticalAlignment = VerticalAlignment.Top;

            var mfgName = new TextBlock { Text = "Lancair IV" };
            mfgName.SetValue(Grid.RowProperty, r);
            mfgName.SetValue(Grid.ColumnProperty, i);
            mfgName.HorizontalAlignment = HorizontalAlignment.Center;

            var price = new TextBlock { Text = "$" + randomNumList[r + i] };
            price.SetValue(Grid.RowProperty, r);
            price.SetValue(Grid.ColumnProperty, i);
            price.HorizontalAlignment = HorizontalAlignment.Left;
            price.VerticalAlignment = VerticalAlignment.Center;
            price.Margin = new Thickness(30, 0, 0, 0);

            this.airplaneGrid.Children.Add(modelImage);
            this.airplaneGrid.Children.Add(mfgName);
            this.airplaneGrid.Children.Add(price);
          }
       }
    }
 }

Эта функция не моя. Извините, забыл названный кредит, но этот парень из стека overoverflow предоставил этому форуму.

 public static class RandomExtensions
 {
    public static int NextDouble(
                    Random random,
                    double minValue,
                    double maxValue)
    {
       return random.Next(10, 50);
    }
 }

Извините, я слишком низко на тотемном столбе, чтобы отправить изображение, но запустите его для полного понимания предполагаемого расположения.

Вот XAML для поддержки вышеизложенного.

 <Grid x:Name="airplaneGrid" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="60" />
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="175"/>
            <ColumnDefinition Width="175"/>
            <ColumnDefinition Width="175"/>
            <ColumnDefinition Width="175"/>
            <ColumnDefinition Width="175"/>
        </Grid.ColumnDefinitions>
    </Grid>

2 ответа

Вы можете использовать другую сетку (или панель стека, или любой другой тип панели) в качестве дочернего элемента в каждой ячейке, а затем добавить дочерние элементы на эту панель.

Хорошо. Я поместил ваше решение и мое из стороны в сторону. Это выглядит так:

введите описание изображения здесь

По общему признанию, это требует немного больше настройки, но вы поймете основную идею.

 <ListView ItemsSource="{Binding}" Grid.Column="1">
            <ListView.Resources>
                <DataTemplate x:Key="CellContentTemplate">
                    <Border BorderBrush="LightGray" BorderThickness="1">
                        <DockPanel>
                            <Image Height="20" Width="20" Source="{Binding ImageSource}" Margin="2"
                               DockPanel.Dock="Left"/>
                            <StackPanel>
                                <TextBlock Text="{Binding Value, StringFormat='${0}'}" Margin="2"/>
                                <TextBlock Text="{Binding Name}" Margin="2"/>
                            </StackPanel>
                        </DockPanel>
                    </Border>

                </DataTemplate>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header=""  DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn Header="Pitts">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ContentPresenter Content="{Binding Pitts}" ContentTemplate="{StaticResource CellContentTemplate}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Vans">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ContentPresenter Content="{Binding Vans}" ContentTemplate="{StaticResource CellContentTemplate}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Lancair">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ContentPresenter Content="{Binding Lancair}" ContentTemplate="{StaticResource CellContentTemplate}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Epic">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ContentPresenter Content="{Binding Epic}" ContentTemplate="{StaticResource CellContentTemplate}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

Код сзади (просто случайные данные):

 Random random = new Random();

        public GridSample() //Window Constructor
        {
            InitializeComponent();

            var names = new[] {"NORTH","SOUTH","EAST","WEST"};


            DataContext = names.Select(x => new GridViewModel()
                                                {
                                                    Name = x,
                                                    Epic = CreateRandomCell(),
                                                    Lancair = CreateRandomCell(),
                                                    Pitts = CreateRandomCell(),
                                                    Vans = CreateRandomCell()
                                                });
        }

        private CellViewModel CreateRandomCell()
        {
            return new CellViewModel
                       {
                           Name = "Cell" + random.Next(0, 100),
                           ImageSource = "/ChessPieces/BlackBishop.png",
                           Value = (decimal) random.Next(0, 100)
                       };
        }

ViewModels:

  public class GridViewModel
    {
        public string Name { get; set; }

        public CellViewModel Pitts { get; set; }

        public CellViewModel Vans { get; set; }

        public CellViewModel Lancair { get; set; }

        public CellViewModel Epic { get; set; }
    }

    public class CellViewModel
    {
        public string Name { get; set; }

        public string ImageSource { get; set; }

        public decimal Value { get; set; }
    }

Увидеть? чистый MVVM, чистое, красивое решение.

Другие вопросы по тегам