none
DriveInfo в Custom ListBox. Помогите ! RRS feed

  • Вопрос

  • Здравствуйте. Пишу для себя небольшую программу и столкнулся с одной проблемой, в интернете разсмотрел немало примеров по ItemContainerStyle но не один мне не помог. Вот у меня есть код:
    using System;
    using System.IO;
    .......
    
    namespace DriveInformer
    {
    
    public partial class MainWindow : Window
      {
          DriveInfo[] d = DriveInfo.GetDrives();
    
          public MainWindow()
             {
                InitializeComponent();
             }
    
          private void Window_Loaded(object sender, RoutedEventArgs e)
             {
               foreach(DriveInfo drive in d)
                   {
                      try
                         {
                            drvProgress.Maximum = ((drive.TotalSize));
                            drvProgress.Value = ((drive.TotalSize) - (drive.TotalFreeSpace));
                            lstBox.Items.Add("Local Disk " +(drive.Name)+ " " +(drive.TotalFreeSpace) /1024 /1024 /1024 + " GB Свободно из " +(drive.TotalSize) /1024 /1024 /1024 + " GB" );
                         }
                        catch (Exception ex)
                         {
                              MessageBox.Show(drive.Name+ " " +ex.Message);
                         {
          }
    }
    
    Мне его надо совместить с ItemContainerStyle так чтобы :
    <TextBlock Name="drvName" Text="{Binding Path=DriveName}" />
    <ProgressBar Name="drvProgress" Maximum="{Binding Path=Maximum}" Value="{Binding Path=Value}" />
    <TextBlock Name="GBofGB" Text="{Binding Path=gbofgb}" />
    

    Помогите пожалуйста кому не лень. По сути я хочу сделать тоже самое когда открываешь My Computer и видно информацию о Fixed дисках.
    14 сентября 2011 г. 5:24

Ответы

  • DriveInfo ничего не знает о том, на какой диск установлена ОС.

    Как вариант:

     

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {           
                var drives = from drv in DriveInfo.GetDrives().AsQueryable()
                             where drv.DriveType == DriveType.Fixed
                             select new
                             {
                                 
                                 DriveName = String.Format("Локальный диск {0}", drv.Name),
                                 Maximum = drv.TotalSize,
                                 Value = (Double)(drv.TotalSize - drv.TotalFreeSpace),
                                 gbofgb = String.Format("{0} GB Свободно из {1} GB", (drv.TotalFreeSpace) / 1024 / 1024 / 1024, (drv.TotalSize) / 1024 / 1024 / 1024),
                                 IsSystem = (drv.Name == System.IO.Path.GetPathRoot(Environment.SystemDirectory))
                             };
                this.diskList.ItemsSource = drives;
            }
    

    А дальше при биндинге к картинке реализовывать IValueConverter, который будет исходя из значения IsSystem возвращать тебе нужную картинку.

     

    • Помечено в качестве ответа Abolmasov Dmitry 14 сентября 2011 г. 10:50
    14 сентября 2011 г. 10:20
    Модератор

Все ответы

  • Здравствуйте.

    Вам нужно вместо

      lstBox.Items.Add("Local Disk " +(drive.Name)+ " " +(drive.TotalFreeSpace) /1024 /1024 /1024 + " GB Свободно из " +(drive.TotalSize) /1024 /1024 /1024 + " GB" );

    добавлять в lstBox объекты класса, который имеет свойства в соответствии с вашим биндингом.


    Для связи [mail]
    14 сентября 2011 г. 5:45
  • На коленке как-то так получается: 

    <ListView ItemsSource="{Binding}" BorderThickness="0" Name="diskList">
                <ListView.ItemContainerStyle>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListViewItem}">
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="10"/>
                                            <RowDefinition Height="*"/>
                                        </Grid.RowDefinitions>
                                        <TextBlock Name="drvName" Text="{Binding Path=DriveName}" Grid.Row="0"/>
                                        <ProgressBar Name="drvProgress" Maximum="{Binding Path=Maximum}" Value="{Binding Path=Value, Mode=OneWay}" Grid.Row="1"/>
                                        <TextBlock Name="GBofGB" Text="{Binding Path=gbofgb}" Grid.Row="2"/>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
    

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {           
                var drives = from drv in DriveInfo.GetDrives().AsQueryable()
                             where drv.DriveType == DriveType.Fixed
                             select new
                             {
                                 DriveName = String.Format("Локальный диск {0}", drv.Name),
                                 Maximum = drv.TotalSize,
                                 Value = (Double)(drv.TotalSize - drv.TotalFreeSpace),
                                 gbofgb = String.Format("{0} GB Свободно из {1} GB", (drv.TotalFreeSpace) / 1024 / 1024 / 1024, (drv.TotalSize) / 1024 / 1024 / 1024)
                             };
                this.diskList.ItemsSource = drives;
            }
    


     

    • Предложено в качестве ответа ulcerModerator 14 сентября 2011 г. 10:20
    14 сентября 2011 г. 6:25
    Модератор
  • Спасибо за наглядный пример ! Теперь думаю разберусь. У меня была проблема с привязкой данных в ItemContainerStyle так как обьекты в StackPanel не были видны для кода даже если у них было присвоено имя типа x:Name.

    А вот и еще что забыл спросить. Как задать обьекту <Image /> картинку так чтоб если Раздел C: (стандартный для установки ОС) то иконка соответствующая, а для остальных другая. На данный момент у меня получается что для всех одна и та же. Просто в описании про DriveIfno на msdn толком не написано ничего как определить. Да там в основном для консоли а я пишу для интерфейса.


    • Изменено nFox86 14 сентября 2011 г. 9:37
    14 сентября 2011 г. 9:36
  • > ... если Раздел C: (стандартный для установки ОС) то иконка соответствующая ...  

    определить системный диск можно так:

    System.Environment.ExpandEnvironmentVariables("%SystemDrive%")

    14 сентября 2011 г. 10:11
  • DriveInfo ничего не знает о том, на какой диск установлена ОС.

    Как вариант:

     

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {           
                var drives = from drv in DriveInfo.GetDrives().AsQueryable()
                             where drv.DriveType == DriveType.Fixed
                             select new
                             {
                                 
                                 DriveName = String.Format("Локальный диск {0}", drv.Name),
                                 Maximum = drv.TotalSize,
                                 Value = (Double)(drv.TotalSize - drv.TotalFreeSpace),
                                 gbofgb = String.Format("{0} GB Свободно из {1} GB", (drv.TotalFreeSpace) / 1024 / 1024 / 1024, (drv.TotalSize) / 1024 / 1024 / 1024),
                                 IsSystem = (drv.Name == System.IO.Path.GetPathRoot(Environment.SystemDirectory))
                             };
                this.diskList.ItemsSource = drives;
            }
    

    А дальше при биндинге к картинке реализовывать IValueConverter, который будет исходя из значения IsSystem возвращать тебе нужную картинку.

     

    • Помечено в качестве ответа Abolmasov Dmitry 14 сентября 2011 г. 10:50
    14 сентября 2011 г. 10:20
    Модератор
  • - коллекция иконок: C:\Program Files\Microsoft Visual Studio 10.0\Common7\VS2010ImageLibrary\
    - если требуется получить системные иконки, то см. SHGetFileInfo (пример)


    • Изменено Malobukv 14 сентября 2011 г. 10:24
    14 сентября 2011 г. 10:24
  • <window x:Class.......
                   xmlns........>
          <Grid>
              <ListView Name="diskList" ItemsSource="{Binding}">
                  <ListView.ItemContainerStyle>
                     <Style TargetType="{x:Type ListViewItem}">
                        <Style.Setters>
                           <Setter Property="Template">
                              <StackPanel Orientation="Horizontal">
                                  <StackPanel Width="49" Height="49">
                                     <Image Width="48" Height="48" Source="/DriveInformer;component/Images/drvicon.png" />
                                  </StackPanel>
                                  <StackPanel>
                                     <TextBlock Name="drvName" Text="{Binding Path=DriveName}" FontFamily="Segoe WP" />
                                     <ProgressBar Name="drvProgress" Width="100" Height="15" Maximum="{Binding Path=Maximum}" Value="{Binding Path=Value}" />
                                     <TextBlock Name="GBofGB" Text="{Binding Path=gbofgb}" FontFamily="Segoe WP" />
                                  </StackPanel>
                              </StackPanel>
                           </Setter>
                        </Style.Setters>
                     </Style>
                  </ListView.ItemContainerStyle>
              </ListView>
          </Grid>
    </window>
    
     Странно но Твой пример выше о ItemContainerStyle работает на ура, а вот мой со StackPanel ругается на

    this.diskList.ItemsSource = drives;

    пишет что ItemsSource должен быть пустым перед применением выше указанной строки. Выше указанный мой ItemContainerStyle

    По идее не вижу в нем проблемы, если только StackPanel не пропускает чтение данных, потому что когда тестирую то ListView пустой и ругается на ту строку.

    Посмотри мельком, может я что то не в том порядке написал или лешнее добавил.

    14 сентября 2011 г. 11:18
  •     <Grid>
            <ListView ItemsSource="{Binding}" BorderThickness="0" Name="diskList">
                <ListView.ItemContainerStyle>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListViewItem}">
                                    <StackPanel Orientation="Horizontal">
                                        <StackPanel Width="49" Height="49">
                                            <Image Width="48" Height="48" Source="/DriveInformer;component/Images/drvicon.png" />
                                        </StackPanel>
                                        <StackPanel>
                                            <TextBlock Name="drvName" Text="{Binding Path=DriveName}" FontFamily="Segoe WP" />
                                            <ProgressBar Name="drvProgress" Width="100" Height="15" Maximum="{Binding Path=Maximum}" Value="{Binding Path=Value, Mode=OneWay}" />
                                            <TextBlock Name="GBofGB" Text="{Binding Path=gbofgb}" FontFamily="Segoe WP" />
                                        </StackPanel>
                                    </StackPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
        </Grid>
    

    14 сентября 2011 г. 11:31
    Модератор