2011-05-30 273 views
8

我有一個通過傳遞對象列表來填充ListView的類。該類使用反射來查看每個對象的屬性以生成ListView。我怎樣才能改變ListView中一行的背景顏色。以編程方式更改ListView行的背景顏色(wpf)

page正是我所期待的。唯一的問題是我的ListView綁定到對象列表。換句話說,ListView的每個項目都是綁定的對象,而不是ListViewItem。我假設這是我無法將ListView中的某些項目轉換爲ListViewItem的原因。例如,當我這樣做:

ListViewItem someItem = (ListViewItem)listView1.Items[0]; 

我得到一個InvalidCastException,因爲如果我在哪裏物理對象添加到喜歡的ListView:

listview.items.add(someObject),那麼這將工作,但因爲我將列表綁定到ListView那一行不起作用。我認爲這就是我無法施展的原因。我想轉換它的原因是因爲ListViewItem具有Background屬性。

編輯

我能夠做到這一點與第12個對象我已經試過了如下因素:

for (int i = 0; i < listView1.Items.Count; i++) 
{ 
    var lvitem = listView1.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem; 
    lvitem.Foreground = Brushes.Green;     
} 

,我得到這個錯誤:

first try

和我也試過這個:

foreach (Tiro t in listView1.Items) 
{ 
    var lvitem = listView1.ItemContainerGenerator.ContainerFromItem(t) as ListViewItem; 
    if (t.numero == 0 || t.numero == 37) 
    { 
     //lvitem.Background = Brushes.Green; 
     lvitem.Foreground = Brushes.Green; 
    } 
    else if (t.numero % 2 == 0) 
    { 
     //lvitem.Background = Brushes.Red; 
     lvitem.Foreground = Brushes.Red; 
    } 
    else 
    { 
     //lvitem.Background = Brushes.Gray; 
     lvitem.Foreground = Brushes.Black; 
    } 

} 

,我也得到了同樣的錯誤:

enter image description here

我不明白爲什麼LVITEM 12迭代後爲空?

它僅與正在顯示的項目工程....

回答

3

使用ItemContainerGenerator時,請注意容器是異步生成的。發電機暴露了狀態改變的情況下,您可以聽:

listView.ItemContainerGenerator.StatusChanged += new EventHandler(ContainerStatusChanged);  

private void ContainerStatusChanged(object sender, EventArgs e) 
{ 
    if (listView.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) 
    { 
     foreach (Tiro t in listView1.Items) 
     { 
      ... 
     } 
    } 
} 

不知道這會造成任何奇怪的繪圖效果(閃爍)或沒有。

另一種選擇,而不是在代碼中構建listview項目是使用數據模板。儘管如此,您可能必須爲視圖模型添加一些屬性才能進行顯示。

3

你可以使用ItemContainerGenerator,如:

var lvitem = listView.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; 
var lvitem = listView.ItemContainerGenerator.ContainerFromIndex(0) as ListViewItem; 

但是默認情況下,ListView被虛擬化,這意味着ListViewItems創建(如果該項目在列表中實際可見),所以上述方法不會返回當前不可見項目的容器。

通常情況下,最好通過ItemContainerStyle中的SetterBackground屬性上定義綁定。

+0

我現在可以做更多的事情了,謝謝。我雖然無法改變顏色。我會繼續嘗試。 – 2011-05-30 02:05:43

+0

lvitem.Background = Brushes.AliceBlue;我需要使用布什而不是顏色 – 2011-05-30 02:10:41

+0

那麼,這是有點常識。 – 2011-05-30 02:11:31

9

您需要引入ViewModels而不是粉碎WPF UI。例如我可以創建一個如下

public class ItemVM : INotifyPropertyChanged // if you want runtime changes to be reflected in the UI 
{ 
    public string Text {... raise property change in setter } 
    public Color BackgroundColor {... ditto... } 
} 

下一頁創建這些對象爲您的DataContext屬性的列表,以便您的ListView可以綁定到它。

​​

現在,所有你需要做的是你的ListView綁定到該集合及導線上UI的DataContext的正確

 <ListView x:Name="MyListView" ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Text}"> 
        <TextBlock.Background> 
         <SolidColorBrush Color="{Binding BackgroundColor}"/> 
        </TextBlock.Background> 
        </TextBlock> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
     <Button Click="Button_Click" Content="Go PaleGreen"/> 

現在改變背景顏色很容易。只需將相應的ItemVM對象的屬性設置爲所需的顏色即可。例如設置所有項目去淡綠

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     foreach (var item in Items) 
      item.BackgroundColor = Colors.PaleGreen; 
    } 
+0

感謝亞爾它的工作..感謝張貼答案 – 2015-10-15 13:02:49

1

假設在ListBox中的項目是類型的富,並在列表框,你會顯示Foo.ItemInfo每個富項目,最後讓我們說有一個屬性狀態決定了您希望每個Foo.ItemInfo相對於背景,前景,字體樣式和工具提示文本顯示在列表框中。基於這些要求,加在你的XAML如下:

<ListBox FontFamily="Courier New" 
     HorizontalAlignment="Left" 
     ... 
     ...other ListBox attributes... 
     ... 
    <ListBox.Resources> 
     <local:BGConverter x:Key="BackgroundConverter"/> 
     <local:FGConverter x:Key="ForegroundConverter"/> 
     <local:FSConverter x:Key="FontStyleConverter"/> 
     <local:TTConverter x:Key="ToolTipConverter"/> 
    </ListBox.Resources> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding ItemInfo}" 
       Background="{Binding Converter={StaticResource BackgroundConverter}}" 
       FontStyle="{Binding Converter={StaticResource FontStyleConverter}}" 
       Foreground="{Binding Converter={StaticResource ForegroundConverter}}" 
       ToolTip="{Binding Converter={StaticResource ToolTipConverter}}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

接下來,添加以下到您的MainWindow.xaml.cs(或任何你已經命名的XAML的隨行文件)在C#:

public class BGConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Foo foo = (Foo)value; 
     string bgColor = "Gray"; 

     switch(foo.Status) 
     { 
      case 0: 
       bgColor = "White"; 
       break; 

      case 1: 
       bgColor = "Cyan"; 
       break; 

      case 2: 
       bgColor = "Yellow"; 
       break; 
     } 

     return bgColor; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class FSConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Foo foo = (Foo)value; 
     string fStyle = "Normal"; 

     switch(foo.Status) 
     { 
      case 0: 
       fStyle = "Normal"; 
       break; 

      case 1: 
       fStyle = "Oblique"; 
       break; 

      case 2: 
       fStyle = "Italic"; 
       break; 
     } 

     return fStyle; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 


public class FGConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Foo foo = (Foo)value; 
     string fgColor = "Black"; 

     switch(foo.Status) 
     { 
      case 0: 
       fgColor = "Blue"; 
       break; 

      case 1: 
       fgColor = "Brown"; 
       break; 

      case 2: 
       fgColor = "DarkBlue"; 
       break; 
     } 

     return fgColor; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class TTipConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Foo foo = (Foo)value; 
     string ttText = "No tool tips for this item."; 

     switch(foo.Status) 
     { 
      case 0: 
       ttText = "The item has not been processed"; 
       break; 

      case 1: 
       ttText = "The item has been processed but not saved"; 
       break; 

      case 2: 
       ttText = "The item has been processed and saved"; 
       break; 
     } 

     return ttText ; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

這是一個方式,我已經找到了工作......毫無疑問,許多其他的方法,你的里程可能會有所不同...

在任何情況下,HTH

1

一些谷歌上搜索,我發現後我自己的解決方案 我正在使用Listview.ItemsSource和作爲我使用的源列表 然後,我可以在List中設置指定ListViewItem的背景,並且只是刷新listview。

XAML:

<ListView x:Name="listView" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1"> 
       <ListView.View> 
        <GridView> 
         <GridViewColumn Header="IP" DisplayMemberBinding="{Binding IP}" Width="Auto"/> 
         <GridViewColumn Header="PING" DisplayMemberBinding="{Binding Ping}" Width="Auto"/> 
         <GridViewColumn Header="Host Name" DisplayMemberBinding="{Binding DNS}" Width="Auto"/> 
         <GridViewColumn Header="Mac" DisplayMemberBinding="{Binding MAC}" Width="Auto"/> 
         <GridViewColumn Header="Výrobce" DisplayMemberBinding="{Binding Manufacturer}" Width="Auto"/> 
        </GridView> 
       </ListView.View> 
      </ListView> 

填充的ListView與灰色背景資料:

List<ListViewItem> ITEMS = new List<ListViewItem>(); 
    private void button_Click(object sender, RoutedEventArgs e) 
    { 
     for (int i = 1; i < 20; i++) 
     { 
      ListViewItem OneItem = new ListViewItem(); 
      OneItem.Background = Brushes.LightGray; 
      OneItem.Content = new Device() { IP = "1.1.1.1", Ping = "30ms", DNS = "XYZ", MAC = "2F:3C:5F:41:F9", Manufacturer = "Intel" }; 
      ITEMS.Add(OneItem); 
      listView.ItemsSource = ITEMS; 
     } 
     listView.Items.Refresh(); 
    } 
    public class Device 
    { 
     public string IP { get; set; } 
     public string Ping { get; set; } 
     public string DNS { get; set; } 
     public string MAC { get; set; } 
     public string Manufacturer { get; set; } 
    } 

的行更改顏色創建方法:

private void ChangeRowColor(int RowIndex,SolidColorBrush NewBackground) 
    { 
     ITEMS[RowIndex].Background = NewBackground; 
     listView.Items.Refresh(); 
    } 

並使用它:

相關問題