Лучший отвечающий
ListView и его возможности

Вопрос
-
Возможно ли в ListView сделать отображение Tile-в (Для режима отображения Tile) аналогично проводнику windows 7. а именно мне нужна строка состояния памяти. Подскажите и растолкуйте)))) За ранее благодарен!!!!!!
- Изменено Dobrii 21 января 2013 г. 11:38
21 января 2013 г. 11:37
Ответы
-
Слепил на коленке:
var imageList = new ImageList(); imageList.ImageSize = SystemIcons.Question.Size; imageList.Images.Add(SystemIcons.Question); imageList.Images.Add(SystemIcons.Information); int sizeWidth = SystemIcons.Error.Width; var listView = new ListView { Parent = this, Dock = DockStyle.Fill, View = View.Tile, LargeImageList = imageList, OwnerDraw = true }; var item1 = new ListViewItem("Disk C:", 0); var item2 = new ListViewItem("Disk D:", 1); listView.Items.Add(item1); listView.Items.Add(item2); listView.DrawItem += (o, e) => { int x = e.Bounds.X; int y = e.Bounds.Y; int h = e.Bounds.Height; int w = e.Bounds.Width; e.Graphics.DrawString(e.Item.Text, listView.Font, Brushes.Black, x + sizeWidth, y); e.Graphics.DrawImage(imageList.Images[e.Item.ImageIndex], x, y); e.Graphics.DrawRectangle(Pens.LightSeaGreen, x + sizeWidth, y + h / 3, x + w - sizeWidth, 10); e.Graphics.FillRectangle(Brushes.LightSeaGreen, x + sizeWidth, y + h / 3, 20, 10); e.Graphics.DrawString("Memory info here", listView.Font, Brushes.Gray, x + sizeWidth, y + h - h / 3); };
В качестве картинок дисков взял системные иконки.
Шрифты и цвета подобрать по вкусу.
Информация об объёме и заполненности диска, конечно, должна дополнительно получаться.
Число 20 в методе FillRectangle означает заполненность диска. Тоже должно получаться дополнительно.
- Предложено в качестве ответа Abolmasov Dmitry 23 января 2013 г. 8:20
- Помечено в качестве ответа Dobrii 25 января 2013 г. 8:22
22 января 2013 г. 10:17
Все ответы
-
Я так понимаю речь о WinRT. Настройка Tile-в достаточно ограничена и позволяет использовать ряд шаблонов
Подробнее читайте тут и по ссылкам внизу статьи.
Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!
- Изменено LXGDARKEditor 21 января 2013 г. 15:32
21 января 2013 г. 12:53Отвечающий -
Нет, речь не о WinRT. У ListView есть свойство View принимающее значения: LargeIcon, Details, SmallIcon, List, Tile. Собственно речь идет о последнем режиме, но не под Windows 8, а под Windows 722 января 2013 г. 5:21
-
В WinForms, если честно, как такое сделать не знаю, но могу предложить реализовать именно этот элемент управления на WPF и интегрировать его в приложение через ElementHost.22 января 2013 г. 5:53
-
В WinForms, вым придется полностью переопределять отрисовку таких элементов. Для WPF, достаточно задать DataTemplate.
22 января 2013 г. 6:36Отвечающий -
а можно поподробнее пожалуйста. приведите пример!!!
22 января 2013 г. 8:12 -
Слепил на коленке:
var imageList = new ImageList(); imageList.ImageSize = SystemIcons.Question.Size; imageList.Images.Add(SystemIcons.Question); imageList.Images.Add(SystemIcons.Information); int sizeWidth = SystemIcons.Error.Width; var listView = new ListView { Parent = this, Dock = DockStyle.Fill, View = View.Tile, LargeImageList = imageList, OwnerDraw = true }; var item1 = new ListViewItem("Disk C:", 0); var item2 = new ListViewItem("Disk D:", 1); listView.Items.Add(item1); listView.Items.Add(item2); listView.DrawItem += (o, e) => { int x = e.Bounds.X; int y = e.Bounds.Y; int h = e.Bounds.Height; int w = e.Bounds.Width; e.Graphics.DrawString(e.Item.Text, listView.Font, Brushes.Black, x + sizeWidth, y); e.Graphics.DrawImage(imageList.Images[e.Item.ImageIndex], x, y); e.Graphics.DrawRectangle(Pens.LightSeaGreen, x + sizeWidth, y + h / 3, x + w - sizeWidth, 10); e.Graphics.FillRectangle(Brushes.LightSeaGreen, x + sizeWidth, y + h / 3, 20, 10); e.Graphics.DrawString("Memory info here", listView.Font, Brushes.Gray, x + sizeWidth, y + h - h / 3); };
В качестве картинок дисков взял системные иконки.
Шрифты и цвета подобрать по вкусу.
Информация об объёме и заполненности диска, конечно, должна дополнительно получаться.
Число 20 в методе FillRectangle означает заполненность диска. Тоже должно получаться дополнительно.
- Предложено в качестве ответа Abolmasov Dmitry 23 января 2013 г. 8:20
- Помечено в качестве ответа Dobrii 25 января 2013 г. 8:22
22 января 2013 г. 10:17 -
ну да все просто!!!!!!!! что я не сообразил сразу. Надоело просто постоянно переписывать DrawItem. Везде где не использую ListView, везде переписываю отрисовку элементов)))))))) а как это реализовать с помощью WPF???22 января 2013 г. 10:30
-
Ну например, вот так.
1. Создаем WPF проект и добавляем в него вот такой класс:
public class Disk { public string Name { get; set; } public double Size { get; set; } public double Used { get; set; } public string Free { get; set; } }
2. Меняем разметку главного окна:
<Grid> <ListView x:Name="lvDrives"> <ListView.ItemTemplate> <DataTemplate> <StackPanel Width="200"> <TextBlock Text="{Binding Name}" /> <ProgressBar Maximum="{Binding Size}" Value="{Binding Used}" /> <TextBlock Text="{Binding Free}" Foreground="Gray" /> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid>
3. Код главного окна:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Loaded += new RoutedEventHandler(MainWindow_Loaded); } void MainWindow_Loaded(object sender, RoutedEventArgs e) { lvDrives.ItemsSource = DriveInfo.GetDrives().Select( di => new Disk { Name = string.Format("{0} ({1}:)", di.VolumeLabel, di.Name), Size = Math.Truncate(di.TotalSize / (1024d * 1024 * 1024)), Used = Math.Truncate((di.TotalSize - di.AvailableFreeSpace) / (1024d * 1024 * 1024)), Free = string.Format("{0} ГБ свободно из {1} ГБ", Math.Truncate(di.AvailableFreeSpace / (1024d * 1024 * 1024)), Math.Truncate(di.TotalSize / (1024d * 1024 * 1024))) } ); } }
4. Запускаем:
Я делал быстро, поэтому внешний вид не полностью скопирован. Но можно и поиграться. Например так:
<Grid> <ListView x:Name="lvDrives" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <ListView.ItemsPanel> <ItemsPanelTemplate> <WrapPanel /> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListView.ItemTemplate> <DataTemplate> <StackPanel Width="200"> <TextBlock Text="{Binding Name}" /> <ProgressBar Maximum="{Binding Size}" Value="{Binding Used}" Height="20" /> <TextBlock Text="{Binding Free}" Foreground="Gray" /> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid>
Тогда визуально это будет вот так:
Как видите, отображение полностью отделено от обработки, что во многих случаях весьма удобно.
- Предложено в качестве ответа Abolmasov Dmitry 23 января 2013 г. 8:20
22 января 2013 г. 12:00Отвечающий -
а именно мне нужна строка состояния памяти.
Я только сейчас обратил внимание на процитированные слова. Если отображать полосу (прогресс-бар) не надо, то в ручной отрисовке DrawItem нет необходимости. Достаточно задать SubItem, и добавить колонки в listView. И вторая строка текста (которая в SubItem) будет отображаться сама.
- Предложено в качестве ответа Abolmasov Dmitry 23 января 2013 г. 8:20
22 января 2013 г. 13:11 -
Привет.
Пожалуйста, не завыбайте отмечать сообщение или сообщения, являющиеся решением вашей проблемы (кнопка "Пометить как ответ").
Спасибо.
Для связи [mail]
23 января 2013 г. 8:20 -
Надоело просто постоянно переписывать DrawItem. Везде где не использую ListView, везде переписываю отрисовку элементов
Там всего-то пять строк кода отрисовки.
Могу предложить другой способ. Сымитировать то же, как это делается в WPF: вкладыванием одних контролов в другие.
var flowLayoutPanel = new FlowLayoutPanel { Parent = this, Dock = DockStyle.Fill }; foreach (var drive in DriveInfo.GetDrives()) { var panel = new FlowLayoutPanel { Parent = flowLayoutPanel }; var driveImage = SystemIcons.Question.ToBitmap(); var pictureBoxDrive = new PictureBox { Parent = panel, Size = driveImage.Size, Image = driveImage }; var labelName = new Label { Parent = panel, Text = drive.Name }; var progressBar = new ProgressBar { Parent = panel, Style = ProgressBarStyle.Continuous }; var labelMemory = new Label { Parent = panel, AutoSize = true }; if (drive.IsReady) { int freeSpace = (int)(drive.AvailableFreeSpace / 1024 / 1024 / 1024); int totalSize = (int)(drive.TotalSize / 1024 / 1024 / 1024); labelMemory.Text = freeSpace + " свободно из " + totalSize; progressBar.Maximum = totalSize; progressBar.Value = totalSize - freeSpace; } else { labelMemory.Text = "Drive is removable"; } }
Вот только в коде не видна иерархия вложенности. Не позволяет C# отобразить наглядно, как в xaml.
23 января 2013 г. 10:47 -
Всем спасибо. использовал DrawItem.Все красиво!!!!!!!!!!!!!!!!!!!!!!!25 января 2013 г. 8:22