2016-08-16 7 views
0

フォームに少しのスタイルを追加しようとしているようです。私はListBoxを持っているし、他のすべての行に代替シェーディングを追加したい。これも可能ですか?私はListBox.Itemsの$ ListBox.Itemsプロパティを見てみましたが、その下にバックグラウンドのオプションは表示されません。何か案は?ListBox交互のシェーディングPowerShell

$ListBox = New-Object System.Windows.Forms.ListBox 
$ListBox.Size = '325,95' 
$ListBox.Location = '345,25' 
$ListBox.Items.Add("Checking...") > $null 

答えて

1

WindowsフォームにListBox制御でこれを行うにする唯一の方法は、各列の実際の描画をハイジャックすることによるものです。

まず、ListBoxDrawModeプロパティを変更します。

$ListBox.DrawMode = [System.Windows.Forms.DrawMode]::OwnerDrawFixed 

これは、私たちはthe DrawItem event経由アイテムのグラフィックレンダリングを上書きすることができます。

ここで必要なのは、アイテムを描画する関数を定義することだけです。選択した項目に影響を与えることなく、交互の行の色を実行すると、this great example in C#が見つかりました。

幸いにも、C#はeasily ported to PowerShell次のとおりです。

$ListBox.add_DrawItem({ 

    param([object]$s, [System.Windows.Forms.DrawItemEventArgs]$e) 

    if ($e.Index -gt -1) 
    { 
     Write-Host "Drawing item at index $($e.Index)" 

     <# If the item is selected set the background color to SystemColors.Highlight 
     or else set the color to either WhiteSmoke or White depending if the item index is even or odd #> 
     $color = if(($e.State -band [System.Windows.Forms.DrawItemState]::Selected) -eq [System.Windows.Forms.DrawItemState]::Selected){ 
      [System.Drawing.SystemColors]::Highlight 
     }else{ 
      if($e.Index % 2 -eq 0){ 
       [System.Drawing.Color]::WhiteSmoke 
      }else{ 
       [System.Drawing.Color]::White 
      } 
     } 

     # Background item brush 
     $backgroundBrush = New-Object System.Drawing.SolidBrush $color 
     # Text color brush 
     $textBrush = New-Object System.Drawing.SolidBrush $e.ForeColor 

     # Draw the background 
     $e.Graphics.FillRectangle($backgroundBrush, $e.Bounds) 
     # Draw the text 
     $e.Graphics.DrawString($s.Items[$e.Index], $e.Font, $textBrush, $e.Bounds.Left, $e.Bounds.Top, [System.Drawing.StringFormat]::GenericDefault) 

     # Clean up 
     $backgroundBrush.Dispose() 
     $textBrush.Dispose() 
    } 
    $e.DrawFocusRectangle() 
}) 

のEt出来上がり:あなたのコードのルックスによって

Alternate row colors in ListBox

+0

優秀!正確に私が必要としたもの。 – nkasco

+0

お寄せください。しかし、@boeproxは正しいですが、Windowsフォームを使用するのではなく、WPFとXAMLの使用を検討してください。ずっとメンテナンス可能 –

0

、あなたはXAMLを使用していないが、私はとにかくこれを追加したいです代わりのアプローチとして。

これを設定するには、UIのフロントエンドコードとしてXAMLを記述し、トリガー内のセッタープロパティを指定してスタイルトリガーを設定します。 ListBoxコントロール内で、ItemContanerStyleプロパティで作成したスタイルの名前を指定し、AlertnationCountを2に指定すると、指定した色で各行がハイライト表示されます。

以下の例は、リストボックスにテキストを追加するときの動作を示しています。

#Build the GUI 
[xml]$xaml = @" 
<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Name="Window" Title="Initial Window" WindowStartupLocation = "CenterScreen" 
    Width = "313" Height = "800" ShowInTaskbar = "True" Background = "lightgray"> 
    <ScrollViewer VerticalScrollBarVisibility="Auto"> 
     <StackPanel > 
      <StackPanel.Resources> 
       <Style x:Key="AlternatingRowStyle" TargetType="{x:Type Control}" > 
        <Setter Property="Background" Value="LightBlue"/> 
        <Setter Property="Foreground" Value="Black"/> 
        <Style.Triggers> 
         <Trigger Property="ItemsControl.AlternationIndex" Value="1">        
          <Setter Property="Background" Value="White"/> 
          <Setter Property="Foreground" Value="Black"/>         
         </Trigger>        
        </Style.Triggers> 
       </Style>  
      </StackPanel.Resources> 
      <TextBox IsReadOnly="True" TextWrapping="Wrap"> 
       Type something and click Add 
      </TextBox> 
      <TextBox x:Name = "inputbox"/> 
      <Button x:Name="button1" Content="Add"/> 
      <Button x:Name="button2" Content="Remove"/> 
      <Expander IsExpanded="True"> 
       <ListBox x:Name="listbox" SelectionMode="Extended" AlternationCount="2"     
       ItemContainerStyle="{StaticResource AlternatingRowStyle}"/> 
      </Expander > 
     </StackPanel> 
    </ScrollViewer > 
</Window> 
"@ 

$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
$Window=[Windows.Markup.XamlReader]::Load($reader) 
  
#region Connect to Controls  
Write-Verbose "Connecting to controls" 
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach { 
    New-Variable -Name $_.Name -Value $Window.FindName($_.Name) -Force 
} 
#endregion Connect to Controls 

$Window.Add_SourceInitialized({ 
    #Have to have something initially in the collection 
    $Script:observableCollection = New-Object System.Collections.ObjectModel.ObservableCollection[string] 
    $listbox.ItemsSource = $observableCollection 
    $inputbox.Focus() 
}) 
  
#Events 
$button1.Add_Click({ 
    $observableCollection.Add($inputbox.text) 
    $inputbox.Clear() 
}) 
$button2.Add_Click({ 
    ForEach ($item in @($listbox.SelectedItems)) { 
     $observableCollection.Remove($item) 
    } 
})  
$Window.ShowDialog() | Out-Null