【问题标题】:Open details panel under currently selected ListBox item在当前选定的 ListBox 项下打开详细信息面板
【发布时间】:2016-11-18 00:45:58
【问题描述】:

我有一个采用以下布局的电影库,使用列表框:

当用户在库中选择电影时,我需要打开一个包含电影详细信息的框,如下所示:

我设法创建了一个间隙和详细信息面板,但不知道如何将它移到那里。

如果有人知道如何做到这一点,或者可以提出更优雅的解决方案,我将不胜感激。

提前致谢。

【问题讨论】:

  • 问题是项目重排和给定项目的详细信息面板是否可以在调整大小等时移动到另一行。如果是这样,这可能会相当棘手。
  • 是的,它确实回流。我想知道是否有可能以某种方式将详细信息面板的位置永久粘贴到带有键的元素(当前选定的项目)
  • @4a-50 嗨,快完成了!

标签: c# wpf xaml layout listbox


【解决方案1】:

我使用了DataGrid,因为它提供了RowDetailsTemplate

每一行只包含一张图片。

共有三个DataGrids

你可以设置你想要的列数。

DataGrids 的样式我还没有做,所以你会看到多余的边框等。我会删除它们,然后更新答案。

您可以按原样使用以下代码:

Xaml

<Window x:Class="WpfApplicationTest.WinNewGrid" ...>
    <Window.Resources>       
        <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
            <DataGridRowsPresenter x:Name="PART_RowsPresenter" IsItemsHost="True" Orientation="Horizontal"/>
        </ItemsPanelTemplate>

        <DataTemplate x:Key="DetailsKey">
          <StackPanel DataContext="{Binding SelectedMovie}">
            <TextBlock Height="50" Background="Red" Text="{Binding SourcePath}"/>
            <TextBlock Height="50" Background="Red" Text="{Binding ID}"/>
          </StackPanel>
         </DataTemplate>
    </Window.Resources>
    <Grid>

        <DataGrid x:Name="Dgrd" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Sets}" RowDetailsTemplate="{StaticResource DetailsKey}">

                                <DataGrid.Columns>
                                    <DataGridTemplateColumn>
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <DataGrid ItemsSource="{Binding MovieImageList}" SelectedItem="{Binding SelectedMovie, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsPanel="{DynamicResource ItemsPanelTemplate1}" AutoGenerateColumns="False">                                                    
                                                    <DataGrid.Columns>
                                                        <DataGridTemplateColumn>
                                                            <DataGridTemplateColumn.CellTemplate>
                                                                <DataTemplate>
                                                                    <Image Source="{Binding SourcePath}" Width="50" Height="50"/>
                                                                </DataTemplate>
                                                            </DataGridTemplateColumn.CellTemplate>
                                                        </DataGridTemplateColumn>
                                                    </DataGrid.Columns>
                                                </DataGrid>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>
                                </DataGrid.Columns>
                            </DataGrid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>


    </Grid>
</Window>

代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace WpfApplicationTest
{
    /// <summary>
    /// Interaction logic for WinNewGrid.xaml
    /// </summary>
    public partial class WinNewGrid : Window
    {
        public WinNewGrid()
        {
            InitializeComponent();

            List<MovieImage> images = new List<MovieImage>();
            foreach (string fileName in System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures"))
            {
                if (fileName.EndsWith("jpg") || fileName.EndsWith("png") || fileName.EndsWith("gif"))
                    images.Add(new MovieImage() { SourcePath = new Uri(fileName, UriKind.Absolute), ID = Guid.NewGuid().ToString() });
            }

            MovieAndDetailsViewModel movieDetailsVm = new MovieAndDetailsViewModel(images);
            movieDetailsVm.Columns = 3;

            this.DataContext = this;
            Dgrd.ItemsSource = movieDetailsVm.ItemsSource;
        }
    }

    public class MovieAndDetailsViewModel
    {
        private MovieSetsViewModel _setViewModel;
        private List<MovieSetsViewModel> _list;
        public IEnumerable<MovieSetsViewModel> ItemsSource 
        { 
            get {
                _setViewModel = new MovieSetsViewModel();
                int pointer = 0;
                int cols = 6;
                List<MovieListViewModel>[] images = Data.Count() % cols > 0 ? new List<MovieListViewModel>[Data.Count() / cols + 1]
                    : new List<MovieListViewModel>[Data.Count() / cols];

                while (pointer < images.Count())
                {
                    MovieListViewModel mlistVm = new MovieListViewModel();
                    for (int i = pointer * cols; i < Data.Count() && i <= pointer * cols + cols - 1; ++i)
                    {
                        MovieImage img = Data.ToList()[i];
                        mlistVm.MovieImageList.Add(img);
                    }
                    _setViewModel.Sets.Add(mlistVm);
                    pointer += 1;
                }

                _list = new[] { _setViewModel }.ToList();
                return _list; 
            }
        }

        public IEnumerable<MovieImage> Data { get; set; }

        public int Columns { get; set; }

        public MovieAndDetailsViewModel(IEnumerable<MovieImage> movieImages)
        {
            Data = movieImages;

            Columns = 4;
        }
    }

    public class MovieSetsViewModel
    {
        public List<MovieListViewModel> Sets { get; set; }

        public MovieSetsViewModel()
        {
            Sets = new List<MovieListViewModel>();
        }
    }

    public class MovieListViewModel
    {
        public List<MovieImage> MovieImageList { get; set; }

        /* This gets updated while choosing a movie in DataGrid */
        public MovieImage SelectedMovie { get; set; }

        public MovieListViewModel()
        {
            MovieImageList = new List<MovieImage>();
            SelectedMovie = new MovieImage();
        }
    }

    public class MovieImage
    {
        public Uri SourcePath { get; set; }
        public string ID { get; set; }
    }
}

【讨论】:

  • 谢谢你,我绝对可以使用它,但据我了解,datagrid 在调整大小时不能自动重排,对吧?手动编辑会很痛苦。
  • @4a-50 这是最明智的解决方案。你在哪里没有提到你的问题中的回流场景。并且回流在任何地方都没有意义,如果您重新调整窗口大小并使其更短,您将如何查看细节?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 2020-07-31
  • 2015-04-05
  • 1970-01-01
相关资源
最近更新 更多